home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / B-C / CDlog / CDlog.p < prev    next >
Encoding:
Text File  |  1990-11-12  |  93.6 KB  |  3,034 lines  |  [TEXT/PJMM]

  1. {    ****************************************************    }
  2. {                                                         C D L O G                                                              }
  3. {    ****************************************************    }
  4. {    CDlog is a TCL-compatible class that uses DLOG and DITL resources to create            }
  5. {    modal and modeless dialogs.  It has all (as far as I know) the capabilities of Dialog    }
  6. {    Manager dialogs, and a few extensions which utilize TCL features:                            }
  7. {}
  8. {    -    It creates a radio group for each sequence of radio buttons, which means            }
  9. {        your code doesn't have to do much to support radio groups, which is what            }
  10. {        you expect of TCL applications.                                                                    }
  11. {}
  12. {    -    It supports command numbers in button, check box, radio button, and control        }
  13. {        titles. (Following the TCL menu convention, put "#number" at the end of the        }
  14. {        title.  If you want a "#" in the title, put it before the "#number", or if the            }
  15. {        item has no command number, put a "#" at the end anyway.)                                }
  16. {}
  17. {    -    It supports tabbing through edit text items (as does the Dialog Manager), but        }
  18. {        it also support shift-tab to go to the previous edit text item.                                }
  19. {}
  20. {    -    It supports various editing capabilites for editText fields.  This is not all-            }
  21. {        inclusive: the edits are ones that I needed.  Still, at least 2 or 3 should be            }
  22. {        useful in your applications.}
  23. {}
  24. {    -    If your application creates a CDModalDesktop (included) rather than CDesktop,    }
  25. {        CDlog can provide Modal Dialogs.  See CDModalDesktop.                                        }
  26. {}
  27. {    CDlog contains a number of classes and a fair amount of code.  It is distributed in    }
  28. {    one source file.   This is probably NOT how you should use    it.  I did it this way to    }
  29. {    simplify distribution.                                                                                             }
  30. {}
  31. {    I did not spend a long time designing CDlog and the associated classes.  I have the    }
  32. {    usual excuses.  I would appreciate positive and/or negative comments or                }
  33. {    suggestions on how it might be improved.                                                                }
  34. {    ****************************************************    }
  35.  
  36. {    10/1/90- }
  37. {    11/1/90        John Cardinal        1.0.  Limited testing.  Not fully commented or documented. }
  38. {    11/12/90    John Cardinal        1.1.  -    Changed SectPanes to correct for zero origin in CList's. }
  39. {                                                            -    Adjusted call to SectPanes in CDRadioGroup.CalcBorder }
  40. {                                                                to correspond to above. }
  41. {                                                            -    Added CDIcon.NewIcon and CDPicture.NewPicture methods. }
  42. {                                                                Changed IDIcon and IDPicture to use Newxxxx methods. }
  43. {                                                            -    Changed CDGraphic.DoClick to react to quick click.  Not sure }
  44. {                                                                if this is correct behavior. }
  45. {                                                            -    Changed CompuServe upload to include example application. }
  46.  
  47. {    *******************************    }
  48. {                                                                                }
  49. {    Copyright © 1990 by John Cardinal                        }
  50. {    All rights reserved.                                                }
  51. {}
  52. {    John Cardinal                                                        }
  53. {    C/O Epsilon                                                            }
  54. {    50 Cambridge Street                                                }
  55. {    Burlington, MA 01803                                            }
  56. {                                                                                }
  57. {    CompuServe: 73230,3725                                    }
  58. {}
  59. {{    You may use this software in commercial or            }
  60. {    non-commercial programs.  You may alter it            }
  61. {    to suit your application needs.  You may distribute    }
  62. {    this source to other users, but you may not            }
  63. {    charge a fee for that distribution, other than            }
  64. {    shipping and handling fees, and the author's name    }
  65. {    and the complete text of this copyright notice        }
  66. {    must be left intact in the source.                            }
  67. {}
  68. {    The author makes no warranty, either express or    }
  69. {    implied, regarding the enclosed computer                }
  70. {    software.  Use this software at your own risk.        }
  71. {}
  72. {    I'd like to acknowledge the efforts of:                    }
  73. {    Gregory H. Dow and Greg Howe    (authers of TCL)    }
  74. {    Philip Keller    (author of CDialog)                            }
  75. {        Belvidere Computing                                            }
  76. {        3002 Belvidere Ave.  S.W.                                }
  77. {        Seattle , WA 98126                                            }
  78. {            (CDialog is a Think C                                        }
  79. {            class that is similar to CDlog)                        }
  80. {    Spec Bowers    (author of AppMaker)                        }
  81. {}
  82. {    I got ideas and in some cases borrowed code            }
  83. {    from software written by the above.                        }
  84. {}
  85. {    For those of you who are familiar with                    }
  86. {    CDialog: CDlog is similar to CDialog in that it            }
  87. {    is a TCL-compatible class that uses DLOG and         }
  88. {    DITL resources to create modeless dialogs.            }
  89. {    Some of the class names are the same. But...            }
  90. {    CDlog uses a different approach.  In particular,        }
  91. {    the main class (CDlog) is a subclass of                    }
  92. {    CDirector (rather than CDocument), and the            }
  93. {    Dialog Manager is not used.                                    }
  94. {    *******************************    }
  95.  
  96. unit CDlog;
  97.  
  98. interface
  99. uses
  100.     Script, TCL;
  101.  
  102. const
  103.     { Constants for use with CDEditText "SetEdit" method. }
  104.     CdCrOkOff = 2;                    { Don't process CR as click on button one. }
  105.     CdEtxOkOff = 4;                { Don't process Enter as click on button one. }
  106.     CdEscOff = 8;                    { Don't process ESC as click on button two. }
  107.     CdCrFiltOn = 16;                { Don't allow CR as input character. }
  108.     CdSpecFiltOn = 32;            { Don't allow special characters, with the exception of TE editing chars. }
  109.     CdNspFiltOn = 64;                { Don't allow characters that are not valid in NSP. }
  110.     CdClidFiltOn = 128;            { Don't allow characters that are not valid in client IDs. }
  111.     CdLenFiltOn = 256;            { Don't allow the field to grow beyond "maxLength" bytes. }
  112.     CdCMSFiltOn = 512;            { Don't allow characters that are not valid in CMS filenames. }
  113.     CdNumFiltOn = 1024;        { Don't allow non-numerics. }
  114.     CdUpDownOn = 2048;        { Treat up and down arrow keys as commands. }
  115.     CdLeftRightOn = 4096;        { Treat left and right arrow keys as commands. }
  116.  
  117.     { NOTE: CdNspFiltOn and CdClidFiltOn are very specific to my applications; I left them}
  118.     { in to avoid having two versions.  Ignore them.}
  119.  
  120.     { Commands issued by CDEditText.DoKeyDown }
  121.     cmdArrowLeft = 2101;        { User pressed left arrow }
  122.     cmdArrowRight = 2102;    { User pressed right arrow }
  123.     cmdArrowUp = 2103;        { User pressed up arrow }
  124.     cmdArrowDown = 2104;    { User pressed down arrow }
  125.     cmdBadChar = 2105;            { *User keyed a character that is invalid for the current field }
  126.     cmdBadLength = 2106;        { *Current field is full; no more characters allowed }
  127.     cmdOkEquiv = 2107;            { User pressed an character that is an equivalent for the OK button }
  128.     cmdCancelEquiv = 2108;    { User pressed an character that is an equivalent for the Cancel button }
  129.  
  130. type
  131.     CDDitlItemRec = record        { This record maps the basics of DITL entries }
  132.             placeHolder: longint;        { A placeholder }
  133.             boundsRect: Rect;            { Location rectangle }
  134.             typeLen: integer;            { First is type, second byte is length }
  135.             dummy: Str255;            {Takes up space; don't reference}
  136.         end;
  137.  
  138.  
  139. {    ****************************************************    }
  140. {     C D C O N T R O L                                                                                                      }
  141. {}
  142. {        CDControl implements ToolBox controls in CDlog dialog windows.  CDControl is    }
  143. {        based on CControl with additions from CButton, in order to allow controls to        }
  144. {        act like buttons.                                                                                                }
  145. {}
  146. {        You should not need to override this class.                                                            }
  147. {}
  148. {        SUPERCLASS = CControl}
  149. {        SUBCLASSES = CDButton, CDCheckBox}
  150. {    ****************************************************    }
  151.     CDControl = object(CControl)
  152.             saveHilite: integer;        { Hilte state (for preserving across activate/deactivate) }
  153.  
  154.             clickCmd: longint;            { Command to issue to supervisor upon GoodClick }
  155.  
  156.             txFont: integer;            { GrafPort characteristics }
  157.             txFace: Style;
  158.             txMode: integer;
  159.             txSize: integer;
  160.  
  161.             procedure IDControl (                                                            { Initialize CDControl }
  162.                                         anEnclosure: CView;
  163.                                         aSupervisor: CBureaucrat;
  164.                                         item: CDDitlItemRec);                                { DITL item info }
  165.  
  166.             procedure IDControlX (                                                        { Extra initialization for CDControl }
  167.                                         item: CDDitlItemRec);                                { DITL item info }
  168.  
  169.             procedure Activate;
  170.             override;
  171.  
  172.             procedure Deactivate;
  173.             override;
  174.  
  175.             procedure Draw (var area: Rect);
  176.             override;
  177.  
  178.             procedure DoGoodClick (whichPart: integer);
  179.             override;
  180.  
  181.             procedure SetClickCmd (aClickCmd: longint);
  182.  
  183.             procedure Hilite (                                                                { Send HiliteControl message to control }
  184.                                         hiliteState: integer);                                    { Passed argument }
  185.         end; {CDControl}
  186.  
  187.  
  188. {    ****************************************************    }
  189. {     C D B U T T O N                                                                                                      }
  190. {}
  191. {        CDButton implements simple buttons in CDlog dialog windows.                            }
  192. {}
  193. {        You should not need to override this class.                                                            }
  194. {}
  195. {        SUPERCLASS = CDControl}
  196. {        SUBCLASSES = CDRadioButton}
  197. {    ****************************************************    }
  198.     CDButton = object(CDControl)
  199.             procedure IDButton (                                                            { Initialize CDButton }
  200.                                         anEnclosure: CView;
  201.                                         aSupervisor: CBureaucrat;
  202.                                         item: CDDitlItemRec);                                { DITL item info }
  203.         end;
  204.  
  205.  
  206. {    ****************************************************    }
  207. {     C D R A D I O B U T T O N                                                                                          }
  208. {}
  209. {        CDRadioButton implements radio buttons in CDlog dialog windows.                        }
  210. {}
  211. {        You should not need to override this class.                                                            }
  212. {}
  213. {        SUPERCLASS = CDButton}
  214. {        SUBCLASSES = None}
  215. {    ****************************************************    }
  216.     CDRadioButton = object(CDButton)
  217.             idNumber: integer;
  218.  
  219.             procedure IDRadioButton (                                                    { Initialize CDRadioButton }
  220.                                         anEnclosure: CView;
  221.                                         aSupervisor: CBureaucrat;
  222.                                         item: CDDitlItemRec;                                    { DITL item }
  223.                                         anIdNumber: integer);                                { ID number used by CRadioGroup }
  224.  
  225.             procedure DoGoodClick (whichPart: integer);
  226.             override;
  227.  
  228.             function GetIdNumber: integer;
  229.         end;
  230.  
  231.  
  232. {    ****************************************************    }
  233. {     C D C H E C K B O X                                                                                                  }
  234. {}
  235. {        CDCheckBox implements check boxes in CDlog dialog windows.                            }
  236. {}
  237. {        You should not need to override this class.                                                            }
  238. {}
  239. {        SUPERCLASS = CDControl}
  240. {        SUBCLASSES = None}
  241. {    ****************************************************    }
  242.     CDCheckBox = object(CDControl)
  243.             procedure IDCheckBox (                                                        { Initialize CDCheckBox }
  244.                                         anEnclosure: CView;
  245.                                         aSupervisor: CBureaucrat;
  246.                                         item: CDDitlItemRec);                                { DITL item info }
  247.  
  248.             procedure DoGoodClick (whichPart: integer);
  249.             override;
  250.  
  251.             procedure ToggleCheck;
  252.  
  253.             function IsChecked: Boolean;
  254.         end;
  255.  
  256.  
  257. {    ****************************************************    }
  258. {     C D G R A P H I C                                                                                                      }
  259. {}
  260. {        CDGRAPHIC is an abstract class used to implement various graphics in CDlog        }
  261. {        dialog windows.                                                                                                    }
  262. {}
  263. {        You should probably not override this class.                                                        }
  264. {}
  265. {        SUPERCLASS = CPane}
  266. {        SUBCLASSES = CDIcon, CDPicture, CDUser}
  267. {    ****************************************************    }
  268.     CDGraphic = object(CPane)
  269.             clickCmd: integer;
  270.             state: integer;
  271.  
  272.             procedure SetClickCmd (                                                    { Set command to issue upon click }
  273.                                         aClickCmd: longint);                                    { Command number }
  274.  
  275.             procedure DoClick (                                                            { Handle clicks }
  276.                                         hitPt: Point;                                                { Mouse location in Frame coords }
  277.                                         modifierKeys: integer;                                { State of modifier keys }
  278.                                         when: longint);                                            { Tick time of mouse click }
  279.             override;
  280.  
  281.             procedure DoGoodClick (                                                        { Handle "good" click }
  282.                                         whichPart: integer);
  283.  
  284.             procedure Hilite (                                                                { Reset hilite state, and redraw }
  285.                                         aState: integer);
  286.         end;
  287.  
  288.  
  289. {    ****************************************************    }
  290. {     C D I C O N                                                                                                              }
  291. {}
  292. {        CDIcon implements icons in CDlog dialog windows.                                                }
  293. {}
  294. {        You should not need to override this class.                                                            }
  295. {}
  296. {        SUPERCLASS = CDGraphic}
  297. {        SUBCLASSES = None}
  298. {    ****************************************************    }
  299.     CDIcon = object(CDGraphic)
  300.             theIconID: integer;
  301.             theIcon: Handle;
  302.  
  303.             procedure IDIcon (                                                                { Initialize CDIcon }
  304.                                         anEnclosure: CView;                                    { Standard IPane parms }
  305.                                         aSupervisor: CBureaucrat;
  306.                                         aWidth: integer;
  307.                                         aHeight: integer;
  308.                                         aHEncl: integer;
  309.                                         aVEncl: integer;
  310.                                         aHSizing: SizingOption;
  311.                                         aVSizing: SizingOption;
  312.                                         anIconID: integer);                                    { ID of ICON resource }
  313.                                                                                                         { (and default clickCmd) }
  314.  
  315.             procedure Free;
  316.             override;
  317.  
  318.             procedure Draw (                                                                { Draw a CDIcon }
  319.                                         var area: Rect);
  320.             override;
  321.  
  322.             procedure NewIcon (                                                            { Change to new icon }
  323.                                         anIconID: integer);
  324.         end; {CDIcon}
  325.  
  326.  
  327. {    ****************************************************    }
  328. {     C D P I C T U R E                                                                                                     }
  329. {}
  330. {        CDPicture implements pictures in CDlog dialog windows.                                    }
  331. {}
  332. {        You should not need to override this class.                                                            }
  333. {}
  334. {        SUPERCLASS = CDGraphic}
  335. {        SUBCLASSES = None}
  336. {    ****************************************************    }
  337.     CDPicture = object(CDGraphic)
  338.             thePictID: integer;                    { ID of PICT resource }
  339.             thePicture: PicHandle;
  340.  
  341.             procedure IDPicture (                                                            { Initialize CDPicture }
  342.                                         anEnclosure: CView;                                    { Standard IPane parms }
  343.                                         aSupervisor: CBureaucrat;
  344.                                         aWidth: integer;
  345.                                         aHeight: integer;
  346.                                         aHEncl: integer;
  347.                                         aVEncl: integer;
  348.                                         aHSizing: SizingOption;
  349.                                         aVSizing: SizingOption;
  350.                                         aPictID: integer);                                        { ID of PICT resource }
  351.                                                                                                         { (and default clickCmd) }
  352.             procedure Free;
  353.             override;
  354.  
  355.             procedure Draw (                                                                { Draw a CDPicture }
  356.                                         var area: Rect);
  357.             override;
  358.  
  359.             procedure NewPicture (                                                        { Change to new picture }
  360.                                         aPictID: integer);
  361.         end; {CDPicture}
  362.  
  363.  
  364. {    ****************************************************    }
  365. {     C D U S E R                                                                                                             }
  366. {}
  367. {        CDUser implements user items in CDlog dialog windows.                                        }
  368. {}
  369. {        NOTE:  I don't recommend using this class.  I provided this class so that I would    }
  370. {        have something to create when a DITL contains a user item.  In real life, it            }
  371. {        would probably be easier to 'manually' add your own panes in the initialize            }
  372. {        method of your CDlog subclass.                                                                            }
  373. {}
  374. {        SUPERCLASS = CDGraphic}
  375. {        SUBCLASSES = None}
  376. {    ****************************************************    }
  377.     CDUser = object(CDGraphic)
  378.             procedure IDUser (                                                                { Initialize CDUser }
  379.                                         anEnclosure: CView;                                    { Standard IPane parms }
  380.                                         aSupervisor: CBureaucrat;
  381.                                         aWidth: integer;
  382.                                         aHeight: integer;
  383.                                         aHEncl: integer;
  384.                                         aVEncl: integer;
  385.                                         aHSizing: SizingOption;
  386.                                         aVSizing: SizingOption);
  387.  
  388.             procedure Hilite (                                                                { Reset hilite state, and redraw }
  389.                                         aState: integer);                                        { New state }
  390.             override;
  391.  
  392.         end; {CDUser}
  393.  
  394. {    ****************************************************    }
  395. {     C D E D I T T E X T                                                                                                 }
  396. {}
  397. {        CDEditText implements editable text fields in CDlog dialog windows.                    }
  398. {}
  399. {        SUPERCLASS = CEditText}
  400. {        SUBCLASSES = None}
  401. {    ****************************************************    }
  402.     CDEditText = object(CEditText)
  403.             clickCmd: longint;            { Command to issue upon click or change to field }
  404.             filter: integer;                { Mask for editing keystrokes }
  405.             maxLength: integer;        { Maximum length of field }
  406.  
  407.             procedure IDEditText (                                                        { Same parameters as CEditText }
  408.                                         anEnclosure: CView;
  409.                                         aSupervisor: CBureaucrat;
  410.                                         aWidth, aHeight, aHEncl, aVEncl: integer;
  411.                                         aHSizing, aVSizing: SizingOption;
  412.                                         aLineWidth: integer);
  413.  
  414.             procedure DoCommand (                                                        { Do a command }
  415.                                         theCommand: longint);
  416.             override;
  417.  
  418.             procedure DoClick (                                                            { Handle clicks }
  419.                                         hitPt: Point;                                                { Mouse location in Frame coords }
  420.                                         modifierKeys: integer;                                { State of modifier keys }
  421.                                         when: longint);                                            { Tick time of mouse click }
  422.             override;
  423.  
  424.             procedure SetClickCmd (                                                    { Set command to issue upon click or change to field }
  425.                                         aClickCmd: longint);                                    { Command number }
  426.  
  427.             procedure DoKeyDown (                                                        { Handle key-down }
  428.                                         theChar: char;                                            { Key character }
  429.                                         keyCode: Byte;                                            { Key code }
  430.                                         macEvent: EventRecord);                            { Mac event record }
  431.             override;
  432.  
  433.             procedure SetSelect (                                                            { Set selection range }
  434.                                         start: longint;                                            { Start of selection range }
  435.                                         stop: longint);                                            { End of selection range }
  436.  
  437.             procedure SetEdit (                                                            { Set editing control variables }
  438.                                         aFilter: integer;                                        { The filter mask }
  439.                                         aMaxLength: integer);                                { The maximum length }
  440.         end;
  441.  
  442. {    ****************************************************    }
  443. {     C D M O D A L D E S K T O P                                                                                     }
  444. {}
  445. {        CDModalDesktop provides the base support required to implement modal CDlog    }
  446. {        dialog windows . }
  447. {}
  448. {        NOTE:  Override the MakeDesktop method in your application class if you want    }
  449. {        to support modal CDlogs dialog windows.  Example:                                            }
  450. {}
  451. {        PROCEDURE CYourApp.MakeDesktop;}
  452. {            VAR}
  453. {                aDeskTop: CDModalDesktop;}
  454. {}
  455. {            BEGIN}
  456. {                new(aDesktop);                    { Use a CDModalDesktop Desktop    }
  457. {                gDeskTop := aDeskTop;        { Set the global variable                 }
  458. {                gDesktop.IDesktop(SELF);    { Send the init message                    }
  459. {            END;}
  460. {}
  461. {        You should not need to override this class.                                                            }
  462. {}
  463. {        SUPERCLASS = CDesktop}
  464. {        SUBCLASSES = None}
  465. {    ****************************************************    }
  466.     CDModalDeskTop = object(CDesktop)
  467.             procedure DispatchClick (var macEvent: EventRecord);
  468.             override;
  469.         end;
  470.  
  471.  
  472. {    ****************************************************    }
  473. {     C D T I T L E D B O R D E R                                                                                      }
  474. {}
  475. {        CTitledBorder implements titled borders.  It is used by CDRadioGroup and other    }
  476. {        classes in CDlog.  It is not dependant on CDlog, however, and may be used in        }
  477. {        any TCL pane.                                                                                                    }
  478. {}
  479. {        You should not need to override this class.                                                            }
  480. {}
  481. {        SUPERCLASS = CBorder}
  482. {        SUBCLASS = None}
  483. {        See also: CDRadioGroup}
  484. {    ****************************************************    }
  485.     CTitledBorder = object(CBorder)
  486.             itsTitle: Str255;            { Title to draw at top left of rectangle }
  487.             txFont: integer;            { GrafPort text characteristics }
  488.             txFace: Style;
  489.             txMode: integer;
  490.             txSize: integer;
  491.  
  492.             procedure ITitledBorder (anEnclosure: CView;
  493.                                         aSupervisor: CBureaucrat;
  494.                                         aWidth, aHeight, aHEncl, aVEncl: integer;
  495.                                         aHSizing, aVSizing: SizingOption;
  496.                                         aTitle: Str255);
  497.  
  498.             procedure SetTitle (                                                            { Set the title }
  499.                                         aTitle: Str255);
  500.  
  501.             procedure Draw (var area: Rect);
  502.             override;
  503.         end;
  504.  
  505.  
  506. {    ****************************************************    }
  507. {     C D R A D I O G R O U P                                                                                              }
  508. {}
  509. {        CDRadioGroup implements radio groups for CDlog dialog windows.                        }
  510. {}
  511. {        The initial reason I needed this class was because I was not using CRadioButton    }
  512. {        (or a subclass), so the usual CRadioGroup class was not an option.  Later, I         }
  513. {        added a titled border, which is the other significant difference between this        }
  514. {        class and CRadioGroup.                                                                                        }
  515. {}
  516. {        You should not need to override this class.                                                            }
  517. {}
  518. {        SUPERCLASS = CBureaucrat}
  519. {        SUBCLASS = None}
  520. {        See also: CDRadioGroup}
  521. {    ****************************************************    }
  522.     CDRadioGroup = object(CBureaucrat)
  523.  
  524.                                 {* Instance Variables *}
  525.  
  526.             itsButtons: CCluster;        { Individual radio buttons        }
  527.             station: CDRadioButton;        { Currently selected button        }
  528.             itsBorder: CTitledBorder;
  529.  
  530.                                 {* Instance Methods *}
  531.  
  532.             procedure IDRadioGroup (anEnclosure: CView;
  533.                                         aSupervisor: CBureaucrat;
  534.                                         aTitle: Str255);
  535.  
  536.             procedure Free;
  537.             override;
  538.  
  539.             procedure AddButton (theRadioButton: CDRadioButton);
  540.  
  541.             procedure RemoveButton (theRadioButton: CDRadioButton);
  542.  
  543.             procedure ChangeStation (theStation: CDRadioButton);
  544.  
  545.             function GetStation: CDRadioButton;
  546.  
  547.             procedure SetStationID (aStationID: integer);
  548.  
  549.             function GetStationID: integer;
  550.  
  551.             procedure CalcBorder (aWidth, aHeight: integer);
  552.  
  553.             procedure SetBorderTitle (aStr: Str255);                            { Set the title of the border }
  554.         end;
  555.  
  556.  
  557. {    ****************************************************    }
  558. {     C D L O G W I N D                                                                                                      }
  559. {}
  560. {        CDlogWind implements the CWindow-subclass for CDlog dialog windows.                }
  561. {}
  562. {        You should not need to override this class.                                                            }
  563. {}
  564. {        SUPERCLASS = CWindow}
  565. {        SUBCLASS = None}
  566. {    ****************************************************    }
  567.     CDlogWind = object(CWindow)                                                        { CWindow except DLOG resource }
  568.             modal: boolean;
  569.  
  570.             procedure IDlogWind (                                                            { Initialize CDlogWind }
  571.                                         DLOGid: integer;                                        { ID of DLOG resource }
  572.                                         aFloating: Boolean;                                    { True if floating window (+FWDesktop)}
  573.                                         anEnclosure: CDesktop;                                { Typically gDeskTop }
  574.                                         aSupervisor: CDirector);                            { Typically gApplication }
  575.  
  576.             procedure MakeMacWindow (                                                { Make Mac ToolBox window }
  577.                                         WINDid: integer);                                        { ID of DLOG resource }
  578.             override;
  579.  
  580.             function GetModal: boolean;
  581.             procedure SetModal (aModal: boolean);
  582.         end; {CDlogWind}
  583.  
  584.  
  585. {    ****************************************************    }
  586. {     C D L O G                                                                                                                  }
  587. {}
  588. {        CDlog implements dialog windows using DITL and DLOG resources.                        }
  589. {}
  590. {        Normally, you create a subclass of CDlog and override the DoCommand method    }
  591. {        (at least) to implement the specific behavior of the dialog.                                    }
  592. {}
  593. {        You may want to override one or more of the MAKEsomething methods, but        }
  594. {        that should be the exception, not the rule.                                                            }
  595. {}
  596. {        SUPERCLASS = CDirector}
  597. {        SUBCLASS = None}
  598. {    ****************************************************    }
  599.     CDlog = object(CDirector)
  600.             itsDocument: CDocument;        { Owner document, if any }
  601.             itsDlogID: integer;                    { ID of DLOG resource }
  602.             itsPanes: CList;                    { List of all items; subclasses of CPane }
  603.             itsTEPanes: CList;                    { List of all CDEditText items }
  604.             itsActiveTE: integer;            { Index to itsTEPanes for active CDEditText item }
  605.             itsRadioGroups: CList;            { List of all RadioGroups }
  606.  
  607.             procedure IDlog (                                                                { Make a dialog }
  608.                                         DLOGid: integer;                                        { DLOG resource id }
  609.                                         aFloating: Boolean;                                    { True if Floating window required; unsupported at present }
  610.                                         aDocument: CDocument;                            { Owner document, if any }
  611.                                         aSupervisor: CApplication;                        { The application }
  612.                                         aFont: integer;                                            { Font for window, text items }
  613.                                         aSize: integer);                                            { Font size for same }
  614.  
  615.             procedure Free;
  616.             override;
  617.  
  618.             function Close (quitting: boolean): boolean;
  619.             override;
  620.  
  621.             procedure GetDItem (                                                            { Get item info    }
  622.                                         item: integer;                                            { The item }
  623.                                         var kind: integer;                                        { Its itemType }
  624.                                         var h: CObject;                                        { Its object reference (CPane) }
  625.                                         var r: Rect);                                            { Its enclosure }
  626.  
  627.             procedure ActivatePrevTE;                                                { Activate previous TE in list }
  628.  
  629.             procedure ActivateNextTE;                                                { Activate next TE in list }
  630.  
  631.             procedure ActivateThisTE (tePane: CDEditText);                { Activate TE that was clicked }
  632.  
  633.             procedure UpdateMenus;                                                        { Enable/disable menu items }
  634.             override;
  635.  
  636.             procedure DoCommand (                                                        { Handle commands }
  637.                                         theCommand: longint);                                { The command number }
  638.             override;
  639.  
  640.             procedure SetEdit (                                                            { Set editing control variables }
  641.                                         anItem: integer;                                        { Item number of edit text field }
  642.                                         aFilter: integer;                                        { The filter mask }
  643.                                         aMaxLength: integer);                                { The maximum length }
  644.  
  645.             procedure GetIText (                                                            { Get item text }
  646.                                         anItem: integer;                                        { Item number of text field }
  647.                                         var str: Str255);                                    { The text in a string }
  648.  
  649.             procedure SetIText (                                                            { Set item text }
  650.                                         anItem: integer;                                        { Item number of text field }
  651.                                         str: Str255);                                            { New text for the item }
  652.  
  653.             procedure DoKeyDown (                                                        { Handle key-down }
  654.                                         theChar: char;                                            { Key character }
  655.                                         keyCode: Byte;                                            { Key code }
  656.                                         macEvent: EventRecord);                            { Mac event record }
  657.             override;
  658.  
  659.             procedure DoButton (                                                            { Simulate clicking a button }
  660.                                         itemNumber: integer);                                { Item number of button to 'click' }
  661.  
  662.             function GetControlHandle (                                                    { Get ControlHandle for give item }
  663.                                         itemNumber: integer): ControlHandle;        { Item number }
  664.  
  665.             function MakeButton (                                                            { Make a CDButton for IDlog }
  666.                                         anEnclosure: CView;
  667.                                         aSupervisor: CBureaucrat;
  668.                                         item: CDDitlItemRec;                                    { DITL item }
  669.                                         enabled: boolean): CPane;                            { True if clicks accepted }
  670.  
  671.             function MakeCheckBox (                                                    { Make a CDCheckBox for IDlog }
  672.                                         anEnclosure: CView;
  673.                                         aSupervisor: CBureaucrat;
  674.                                         item: CDDitlItemRec;                                    { DITL item }
  675.                                         enabled: boolean): CPane;                            { True if clicks accepted }
  676.  
  677.             function MakeRadioButton (                                                    { Make a CDRadioButton for IDlog }
  678.                                         anEnclosure: CView;
  679.                                         aSupervisor: CBureaucrat;
  680.                                         item: CDDitlItemRec;                                    { DITL item }
  681.                                         enabled: boolean;                                        { True if clicks accepted }
  682.                                         anId: integer): CPane;                                { ID number used by CRadioGroup }
  683.  
  684.             function MakeControl (                                                        { Make a CDControl for IDlog }
  685.                                         anEnclosure: CView;
  686.                                         aSupervisor: CBureaucrat;
  687.                                         item: CDDitlItemRec;                                    { DITL item }
  688.                                         enabled: boolean): CPane;                            { True if clicks accepted }
  689.  
  690.             function MakeIcon (                                                                { Make a CDIcon for IDlog }
  691.                                         anEnclosure: CView;
  692.                                         aSupervisor: CBureaucrat;
  693.                                         item: CDDitlItemRec;                                    { DITL item }
  694.                                         enabled: boolean): CPane;                            { True if clicks accepted }
  695.  
  696.             function MakePicture (                                                        { Make a CDPicture for IDlog }
  697.                                         anEnclosure: CView;
  698.                                         aSupervisor: CBureaucrat;
  699.                                         item: CDDitlItemRec;                                    { DITL item }
  700.                                         enabled: boolean): CPane;                            { True if clicks accepted }
  701.  
  702.             function MakeUser (                                                             { Make a CDUser for IDlog }
  703.                                         anEnclosure: CView;
  704.                                         aSupervisor: CBureaucrat;
  705.                                         item: CDDitlItemRec;                                    { DITL item }
  706.                                         enabled: boolean): CPane;                            { True if clicks accepted }
  707.  
  708.             function MakeEditText (                                                        { Make a CDEditText for IDlog }
  709.                                         anEnclosure: CView;
  710.                                         aSupervisor: CBureaucrat;
  711.                                         item: CDDitlItemRec;                                    { DITL item }
  712.                                         enabled: boolean): CPane;                            { True if clicks accepted }
  713.  
  714.             function MakeStaticText (                                                    { Make a CStaticText for IDlog }
  715.                                         anEnclosure: CView;
  716.                                         aSupervisor: CBureaucrat;
  717.                                         item: CDDitlItemRec;                                    { DITL item }
  718.                                         enabled: boolean): CPane;                            { True if clicks accepted }
  719.         end;
  720.  
  721. {    ****************************************************    }
  722. {     P R O C E D U R A L  U T I L I T I E S    }
  723. {    ****************************************************    }
  724.  
  725. {    ****************************************************    }
  726. {    SectPanes }
  727. {}
  728. {    SectPanes is a utility that constructs a rectangle that encloses a series of CPane    }
  729. {    objects stored in a list (CCluster or CList).  If you had 10 CPane (or subclass)        }
  730. {    objects in a list, you could make a rectangle that encloses the 3rd, 4th and 5th        }
  731. {    with:}
  732. {}
  733. {    SectPane(thePaneList, 3, 5, theEnclosingRect);}
  734. {}
  735. {    ****************************************************    }
  736. procedure SectPanes (                                                    { Construct enclosing frame from }
  737.                                                                                         { a series of CPanes in a list }
  738.                             list: CCluster;                                        { The list of panes }
  739.                             first, last: integer;                                { The first and last the define the series }
  740.                             var theFrame: Rect);                            { The enclosing rectangle }
  741.  
  742.  
  743. implementation
  744.  
  745. const
  746.     BORDER_OFFSET = 3;
  747.  
  748. type
  749.     CDlogTemplate = record                            { DLOG template - see IM I-423 for details }
  750.             boundsRect: Rect;
  751.             WDEFid: integer;
  752.             visible: integer;
  753.             goAwayFlag: integer;
  754.             refCon: longint;
  755.             itemsID: integer;
  756.             title: Str255;
  757.         end; {CDlogTemplate}
  758.     CDlogTemplateP = ^CDlogTemplate;
  759.     CDlogTemplateH = ^CDlogTemplateP;
  760.  
  761.     CCntlTemplate = record                            { CNTL template - see IM I-333 for details }
  762.             boundsRect: Rect;
  763.             value: integer;
  764.             isVisible: integer;
  765.             max: integer;
  766.             min: integer;
  767.             procID: integer;
  768.             refCon: longint;
  769.             title: Str255;
  770.         end; {CCntlTemplate}
  771.     CCntlTemplateP = ^CCntlTemplate;
  772.     CCntlTemplateH = ^CCntlTemplateP;
  773.  
  774.  
  775. {    ****************************************************    }
  776. {     C D F R E E C H O R E        }
  777. {}
  778. {        CDFreeChore sends a Free message to an object at "urgent chore" time.  This        }
  779. {        approach avoids conflicts when an object should to be free'd, but methods in        }
  780. {        the call chain may need it to survive until the call chain is unwound.                    }
  781. {}
  782. {        Not used at present.}
  783. {}
  784. {        SUPERCLASS = CChore}
  785. {        SUBCLASS = None}
  786. {    ****************************************************    }
  787.     CDFreeChore = object(CChore)
  788.             theObject: CObject;                                                { The object to be Free'd }
  789.  
  790.             procedure IDFreeChore (anObject: CObject);        { Set 'theObject' and AssignUrgentChore }
  791.             procedure Perform (var maxSleep: longint);        { Free theObject }
  792.             override;
  793.         end;
  794.  
  795.  
  796. {    ****************************************************    }
  797. {     P R O C E D U R A L  U T I L I T I E S    }
  798. {    ****************************************************    }
  799. procedure SectPanes (                                                        { Construct enclosing frame from }
  800.                                                                                             { series of CPanes in a list }
  801.                                 list: CCluster;                                        { The panes }
  802.                                 first, last: integer;                                { The first and last the define the series }
  803.                                 var theFrame: Rect);                            { The enclosing rectangle }
  804.     var
  805.         aPane: CPane;
  806.         index: integer;
  807.         aRect: Rect;
  808.  
  809.     begin
  810.         with theFrame do begin
  811.             left := 32767;
  812.             top := 32767;
  813.             right := 0;
  814.             bottom := 0;
  815.         end;
  816.  
  817.         for index := first to last do begin
  818.             aPane := CPane(list.items^^[index - 1]);
  819.             aPane.GetFrame(aRect);
  820.             aPane.FrameToEnclR(aRect);
  821.  
  822.             with aRect do begin
  823.                 if left < theFrame.left then
  824.                     theFrame.left := left;
  825.                 if top < theFrame.top then
  826.                     theFrame.top := top;
  827.                 if right > theFrame.right then
  828.                     theFrame.right := right;
  829.                 if bottom > theFrame.bottom then
  830.                     theFrame.bottom := bottom;
  831.             end;
  832.         end;
  833.     end;
  834.  
  835.  
  836. {    ****************************************************}
  837. {    PositionDlog}
  838. {}
  839. {        Center the bounding box of a dialog or alert in the upper third}
  840. {        of the screen.  This is the preferred location according to the}
  841. {        Human Interface Guidelines.}
  842. {}
  843. {        A modified version taken from PositionDialog in TCL.p; avoids conflict with}
  844. {        menubar when dialog has titlebar by using bigger offset from top (27 v 7).}
  845. {    ****************************************************}
  846. procedure PositionDlog (theType: ResType;
  847.                                 theID: integer);
  848.  
  849.     var
  850.         theRect: Rect;
  851.         theRectPtr: RectPtr;        { Ptr to bounding box of dialog    }
  852.         theTemplate: Handle;        { Handle to resource template    }
  853.         left,                                { Left side of centered rect        }
  854.         top: integer;                    { Top side of centered rect        }
  855.  
  856.     begin
  857.  
  858.         { The first field of the resource template for DLOG's and ALRT's     }
  859.         { is its bounding box.  Get a pointer to this rectangle.  This               }
  860.         { handle dereferencing is safe since the remaining statements in     }
  861.         { this function do not move memory (assignment and simple math).     }
  862.  
  863.         theTemplate := GetResource(theType, theID);
  864.         CheckResource(theTemplate);
  865.         theRectPtr := RectPtr(theTemplate^);
  866.         theRect := theRectPtr^;
  867.  
  868.         { Center horizontally on screen    }
  869.  
  870.         left := (screenBits.bounds.right - (theRect.right - theRect.left)) div 2;
  871.  
  872.         { Leave twice as much space as above     }
  873.  
  874.         top := (screenBits.bounds.bottom - (theRect.bottom - theRect.top)) div 3;
  875.  
  876.         { Don't put rect under menu bar    }
  877.  
  878.         if top < GetMBarHeight + 27 then
  879.             top := GetMBarHeight + 27;
  880.  
  881.         theRect.right := theRect.right + left - theRect.left;
  882.         theRect.left := left;
  883.         theRect.bottom := theRect.bottom + top - theRect.top;
  884.         theRect.top := top;
  885.  
  886.         theRectPtr^ := theRect;
  887.     end;
  888.  
  889.  
  890. function ParseCmdNumber (var aTitle: Str255): longint;
  891.     var
  892.         cmdNumber: longint;
  893.         cmdString: Str255;
  894.         i: integer;
  895.  
  896.     begin {ParseCmdNumber}
  897.         for i := length(aTitle) downto 1 do
  898.             if aTitle[i] = '#' then begin
  899.                 cmdString := Copy(aTitle, i + 1, length(aTitle) - i);
  900. {$PUSH}
  901. {$R-}
  902.                 aTitle[0] := Chr(i - 1);
  903. {$POP}
  904.                 StringToNum(cmdString, cmdNumber);
  905.                 ParseCmdNumber := cmdNumber;
  906.                 Exit(ParseCmdNumber);
  907.             end;
  908.         ParseCmdNumber := 0;
  909.     end; {ParseCmdNumber}
  910.  
  911.  
  912. {    ****************************************************    }
  913. {     C D F R E E C H O R E   M E T H O D S    }
  914. {    ****************************************************    }
  915. {    IDFreeChore                                                                                                            }
  916. {}
  917. {        Initialize a CDFreeChore.                                                                                    }
  918. {}
  919. {    ****************************************************    }
  920. procedure CDFreeChore.IDFreeChore (anObject: CObject);
  921.     begin
  922.         theObject := anObject;
  923.         gApplication.AssignUrgentChore(SELF);
  924.     end;
  925.  
  926. {    ****************************************************    }
  927. {    Perform                                                                                                                }
  928. {}
  929. {        Free an object.}
  930. {}
  931. {    ****************************************************    }
  932. procedure CDFreeChore.Perform (var maxSleep: longint);
  933.     begin
  934.         theObject.Free;
  935.     end;
  936.  
  937.  
  938. {    ****************************************************    }
  939. {    C D C O N T R O L    M E T H O D S                                                                            }
  940. {    ****************************************************    }
  941. {    IDControl                                                                                                                }
  942. {}
  943. {        First step in initializing a CDControl.  A CDControl acts more like CButton than    }
  944. {        CControl.                                                                                                            }
  945. {}
  946. {    ****************************************************    }
  947. procedure CDControl.IDControl (anEnclosure: CView;
  948.                                 aSupervisor: CBureaucrat;
  949.                                 item: CDDitlItemRec);
  950.     var
  951.         resID: integer;
  952.         controlTmpl: CCntlTemplateH;
  953.         aRect: Rect;
  954.  
  955.     begin
  956.         IView(anEnclosure, aSupervisor);
  957.  
  958.         macPort := itsEnclosure.GetMacPort;
  959.         resID := IntPtr(Ord(@item) + sizeOf(CDDitlItemRec) - sizeOf(Str255))^;
  960.  
  961.         controlTmpl := CCntlTemplateH(GetResource('CNTL', resID));
  962.         CheckResource(Handle(controlTmpl));
  963.  
  964.         HLock(Handle(controlTmpl));
  965.         with controlTmpl^^ do begin
  966.             with boundsRect do
  967.                 OffsetRect(boundsRect, -left, -top);
  968.             with item.boundsRect do
  969.                 OffsetRect(controlTmpl^^.boundsRect, left, top);
  970.             clickCmd := ParseCmdNumber(title);
  971.             macControl := NewControl(macPort, boundsRect, title, (isVisible <> 0), value, min, max, procID, refCon);{(controlTmpl^^.isVisible <> 0)}
  972.         end;
  973.         HUnlock(Handle(controlTmpl));
  974.         ReleaseResource(Handle(controlTmpl));
  975.  
  976.         IDControlX(item);
  977.     end;
  978.  
  979.  
  980. {    ****************************************************    }
  981. {    IDControlX                                                                                                            }
  982. {}
  983. {        Second step in initializing a CDControl.                                                                  }
  984. {}
  985. {    ****************************************************    }
  986. procedure CDControl.IDControlX (item: CDDitlItemRec);
  987.     begin
  988.         txFont := macPort^.txFont;
  989.         txFace := macPort^.txFace;
  990.         txMode := macPort^.txMode;
  991.         txSize := macPort^.txSize;
  992.         saveHilite := macControl^^.contrlHilite;
  993.  
  994.         visible := (macControl^^.contrlVis = 255);
  995.         active := TRUE;
  996.         autoRefresh := TRUE;
  997.         wantsClicks := TRUE;
  998.  
  999.         hEncl := item.boundsRect.left;
  1000.         vEncl := item.boundsRect.top;
  1001.         with macControl^^.contrlRect do begin
  1002.             width := right - left;
  1003.             height := bottom - top;
  1004.         end; {with macControl^^.contrlRect}
  1005.  
  1006.         hSizing := sizFIXEDSTICKY;
  1007.         vSizing := sizFIXEDSTICKY;
  1008.  
  1009.         CalcFrame;
  1010.         CalcAperture;
  1011.  
  1012.         itsEnvironment := nil;
  1013.         itsEnclosure.AddSubview(self);
  1014.     end; {IDControlX}
  1015.  
  1016.  
  1017. {    ****************************************************    }
  1018. {    Draw (OVERRIDE)}
  1019. {}
  1020. {        Other classes are not as nice as they should be; they change the GrafPort's        }
  1021. {        text characteristics and don't restore them: This class saves the info                }
  1022. {        and restores it before drawing.                                                                            }
  1023.  
  1024. {}
  1025. {    ****************************************************    }
  1026. procedure CDControl.Draw (var area: Rect);
  1027.     begin
  1028.         TextFont(txFont);
  1029.         TextFace(txFace);
  1030.         TextMode(txMode);
  1031.         TextSize(txSize);
  1032.  
  1033.         inherited Draw(area);
  1034.     end;
  1035.  
  1036.  
  1037. {****************************************************}
  1038. { Activate (OVERRIDE)}
  1039. {}
  1040. {        Activate a Control}
  1041. {}
  1042. {****************************************************}
  1043.  
  1044. procedure CDControl.Activate;
  1045.     var
  1046.         tempRect: Rect;
  1047.  
  1048.     begin
  1049.         if not active then begin
  1050.             active := TRUE;
  1051.  
  1052.             Prepare;
  1053.             HidePen;
  1054.             HiliteControl(macControl, saveHilite);
  1055.             ShowPen;
  1056.  
  1057.             tempRect := aperture;
  1058.             DrawAll(tempRect);
  1059.  
  1060.             FrameToWindR(tempRect);
  1061.             ValidRect(tempRect);
  1062.         end;
  1063.     end;
  1064.  
  1065.  
  1066. {****************************************************}
  1067. { Deactivate (OVERRIDE)}
  1068. {}
  1069. {        Deactivate a Control}
  1070. {}
  1071. {****************************************************}
  1072.  
  1073. procedure CDControl.Deactivate;
  1074.     var
  1075.         tempRect: Rect;
  1076.  
  1077.     begin
  1078.         if active then begin
  1079.             saveHilite := macControl^^.contrlHilite;
  1080.  
  1081.             active := FALSE;
  1082.  
  1083.             Prepare;
  1084.             HidePen;
  1085.             HiliteControl(macControl, 255);
  1086.             ShowPen;
  1087.  
  1088.             tempRect := aperture;
  1089.             DrawAll(tempRect);
  1090.         end;
  1091.     end;
  1092.  
  1093.  
  1094. {**** C L I C K    H A N D L I N G    M E T H O D S ****}
  1095.  
  1096.  
  1097.  
  1098. {    ****************************************************    }
  1099. {    DoGoodClick (OVERRIDE)}
  1100. {}
  1101. {        A CDControl responds to a good click (the mouse being pressed                            }
  1102. {        and released within the button) by passing a particular command                        }
  1103. {        to its supervisor.                                                                                                }
  1104. {}
  1105. {    ****************************************************    }
  1106. procedure CDControl.DoGoodClick (whichPart: integer);
  1107.     begin
  1108.         if clickCmd <> cmdNull then                { Issue the appropriate command    }
  1109.             itsSupervisor.DoCommand(clickCmd);
  1110.     end;
  1111.  
  1112.  
  1113. {    ****************************************************    }
  1114. {    SetClickCmd}
  1115. {}
  1116. {        Specify the command which is sent to a CDControl's supervisor                            }
  1117. {        after a confirmed click.                                                                                        }
  1118. {}
  1119. {    ****************************************************    }
  1120. procedure CDControl.SetClickCmd (aClickCmd: longint);
  1121.     begin
  1122.         clickCmd := aClickCmd;                { Set instance variable            }
  1123.     end;
  1124.  
  1125.  
  1126. {    ****************************************************    }
  1127. {    Hilite}
  1128. {}
  1129. {        Interface to the Control Manager HiliteControl procedure.                                    }
  1130. {}
  1131. {    ****************************************************    }
  1132. procedure CDControl.Hilite (                                                    { Send HiliteControl message to control }
  1133.                                 hiliteState: integer);                                    { Passed argument }
  1134.     begin
  1135.         Prepare;
  1136.         HiliteControl(macControl, hiliteState);
  1137.         saveHilite := hiliteState;
  1138.     end;
  1139.  
  1140. {    ****************************************************    }
  1141. {    C D B U T T O N    M E T H O D S                                                                                }
  1142. {    ****************************************************    }
  1143. {    IDButton                                                                                                                }
  1144. {}
  1145. {        Initialize a CDButton.                                                                                            }
  1146. {}
  1147. {    ****************************************************    }
  1148. procedure CDButton.IDButton (anEnclosure: CView;
  1149.                                 aSupervisor: CBureaucrat;
  1150.                                 item: CDDitlItemRec);
  1151.     var
  1152.         theTitle: Str255;
  1153.  
  1154.     begin
  1155.         IView(anEnclosure, aSupervisor);
  1156.         macPort := itsEnclosure.GetMacPort;
  1157.         with item do begin
  1158.             theTitle := StringPtr(Ord(@item) + sizeOf(CDDitlItemRec) - SizeOf(Str255) - 1)^;
  1159.             clickCmd := ParseCmdNumber(theTitle);
  1160.             macControl := NewControl(macPort, boundsRect, theTitle, TRUE, 0, 0, 1, pushButProc, 0);
  1161.         end;
  1162.  
  1163.         IDControlX(item);
  1164.     end; {IDButton}
  1165.  
  1166.  
  1167. {    ****************************************************    }
  1168. {    C D R A D I O B U T T O N    M E T H O D S                                                                }
  1169. {    ****************************************************    }
  1170. {    IDRadioButton                                                                                                        }
  1171. {}
  1172. {        Initialize a CDRadioButton.                                                                                    }
  1173. {}
  1174. {    ****************************************************    }
  1175. procedure CDRadioButton.IDRadioButton (anEnclosure: CView;
  1176.                                 aSupervisor: CBureaucrat;
  1177.                                 item: CDDitlItemRec;
  1178.                                 anIdNumber: integer);
  1179.     var
  1180.         theTitle: Str255;
  1181.  
  1182.     begin
  1183.         IView(anEnclosure, aSupervisor);
  1184.         macPort := itsEnclosure.GetMacPort;
  1185.         with item do begin
  1186.             theTitle := StringPtr(Ord(@item) + sizeOf(CDDitlItemRec) - SizeOf(Str255) - 1)^;
  1187.             clickCmd := ParseCmdNumber(theTitle);
  1188.             macControl := NewControl(macPort, boundsRect, theTitle, TRUE, 0, 0, 1, radioButProc, 0);
  1189.         end;
  1190.  
  1191.         IDControlX(item);
  1192.  
  1193.         idNumber := anIdNumber;
  1194.     end; {IDRadioButton}
  1195.  
  1196.  
  1197. {    ****************************************************    }
  1198. {    DoGoodClick (OVERRIDE)}
  1199. {}
  1200. {        A RadioButton responds to a good click (the mouse being pressed and                    }
  1201. {        released within the button) by relaying a command to its supervisor                    }
  1202. {        if it is not already selected.                                                                                }
  1203. {}
  1204. {    ****************************************************    }
  1205. procedure CDRadioButton.DoGoodClick (whichPart: integer);
  1206.     begin
  1207.         if GetCtlValue(macControl) = BUTTON_OFF then
  1208.             CDRadioGroup(itsSupervisor).ChangeStation(SELF);
  1209.  
  1210.         if clickCmd <> cmdNull then                { Issue the appropriate command    }
  1211.             itsSupervisor.DoCommand(clickCmd);
  1212.     end;
  1213.  
  1214.  
  1215. {    ****************************************************    }
  1216. {    GetIdNumber}
  1217. {}
  1218. {        Return id number of a CDRadioButton.                                                                }
  1219. {}
  1220. {    ****************************************************    }
  1221. function CDRadioButton.GetIdNumber: integer;
  1222.     begin
  1223.         GetIdNumber := idNumber;                    { Return instance variable }
  1224.     end;
  1225.  
  1226.  
  1227. {    ****************************************************    }
  1228. {    C D C H E C K B O X    M E T H O D S                                                                        }
  1229. {    ****************************************************    }
  1230. {    IDCheckBox                                                                                                            }
  1231. {}
  1232. {        Initialize a CDCheckBox.                                                                                    }
  1233. {}
  1234. {    ****************************************************    }
  1235. procedure CDCheckBox.IDCheckBox (anEnclosure: CView;
  1236.                                 aSupervisor: CBureaucrat;
  1237.                                 item: CDDitlItemRec);
  1238.     var
  1239.         theTitle: Str255;
  1240.  
  1241.     begin
  1242.         IView(anEnclosure, aSupervisor);
  1243.         macPort := itsEnclosure.GetMacPort;
  1244.         with item do begin
  1245.             theTitle := StringPtr(Ord(@item) + sizeOf(CDDitlItemRec) - SizeOf(Str255) - 1)^;
  1246.             clickCmd := ParseCmdNumber(theTitle);
  1247.             macControl := NewControl(macPort, boundsRect, theTitle, TRUE, 0, 0, 1, checkBoxProc, 0);
  1248.         end;
  1249.  
  1250.         IDControlX(item);
  1251.     end; {IDCheckBox}
  1252.  
  1253.  
  1254. {    ****************************************************    }
  1255. {    DoGoodClick (OVERRIDE)}
  1256. {}
  1257. {        A CDCheckBox responds to a good click (the mouse being pressed}
  1258. {        and released within the button) by flipping the setting on/off}
  1259. {        and possibly passing a command to its supervisor. Under most}
  1260. {        circumstances, there will be no such command.}
  1261. {}
  1262. {    ****************************************************    }
  1263.  
  1264. procedure CDCheckBox.DoGoodClick (whichPart: integer);
  1265.     begin
  1266.         SetValue(1 - GetCtlValue(macControl));
  1267.  
  1268.         if clickCmd <> cmdNull then                { Issue the appropriate command    }
  1269.             itsSupervisor.DoCommand(clickCmd);
  1270.     end;
  1271.  
  1272.  
  1273. {    ****************************************************    }
  1274. {    ToggleChecked}
  1275. {}
  1276. {        Reverse CDCheckBox; checked to unchecked and vice-versa}
  1277. {}
  1278. {    ****************************************************    }
  1279.  
  1280. procedure CDCheckBox.ToggleCheck;
  1281.     begin
  1282.         SetValue(1 - GetCtlValue(macControl));
  1283.     end;
  1284.  
  1285.  
  1286. {    ****************************************************    }
  1287. {    IsChecked}
  1288. {}
  1289. {        Determine whether a CDCheckBox is checked or unchecked}
  1290. {}
  1291. {    ****************************************************    }
  1292.  
  1293. function CDCheckBox.IsChecked: Boolean;
  1294.     begin
  1295.         IsChecked := GetCtlValue(macControl) = BUTTON_ON;
  1296.     end;
  1297.  
  1298.  
  1299. {    ****************************************************    }
  1300. {    C D G R A P H I C    M E T H O D S                                                                            }
  1301. {    ****************************************************    }
  1302. {    SetClickCmd                                                                                                            }
  1303. {}
  1304. {        Specify the command which is sent to a CDGraphic's supervisor                            }
  1305. {        after a confirmed click.                                                                                        }
  1306. {}
  1307. {    ****************************************************    }
  1308. procedure CDGraphic.SetClickCmd (aClickCmd: longint);
  1309.     begin
  1310.         clickCmd := aClickCmd;                { Set instance variable            }
  1311.     end;
  1312.  
  1313.  
  1314. {    ****************************************************    }
  1315. {    DoClick                                                                                                                    }
  1316. {}
  1317. {        Handle a mouse click on a graphic.                                                                        }
  1318. {}
  1319. {    ****************************************************    }
  1320. procedure CDGraphic.DoClick (hitPt: Point;
  1321.                                 modifierKeys: integer;
  1322.                                 when: longint);
  1323.     var
  1324.         inRect: boolean;
  1325.         aRect: Rect;
  1326.         aPoint: Point;
  1327.  
  1328.     begin
  1329.         inRect := TRUE;
  1330.         Hilite(Ord(inRect));
  1331.         aRect := frame;
  1332.         while StillDown do begin
  1333.             GetMouse(aPoint);
  1334.             if PtInRect(aPoint, aRect) <> inRect then begin
  1335.                 inRect := not inRect;
  1336.                 Hilite(Ord(inRect));
  1337.             end; {if PtInRect(aPoint, aRect) <> inRect}
  1338.         end; {WHILE StillDown}
  1339.  
  1340.         if inRect then
  1341.             DoGoodClick(Ord(inRect));
  1342.     end; {DoClick}
  1343.  
  1344.  
  1345. {    ****************************************************    }
  1346. {    DoGoodClick                                                                                                            }
  1347. {}
  1348. {        A CDGraphic responds to a good click (the mouse being pressed                            }
  1349. {        and released within the button) by passing a particular command                        }
  1350. {        to its supervisor, and setting state to Ord(FALSE).                                            }
  1351. {}
  1352. {    ****************************************************    }
  1353. procedure CDGraphic.DoGoodClick (whichPart: integer);
  1354.     begin
  1355.         Hilite(Ord(FALSE));
  1356.  
  1357.         if clickCmd <> cmdNull then                { Issue the appropriate command    }
  1358.             itsSupervisor.DoCommand(clickCmd);
  1359.     end;
  1360.  
  1361.  
  1362. {    ****************************************************    }
  1363. {    Hilite                                                                                                                    }
  1364. {}
  1365. {        Handle a mouse click on a graphic.                                                                        }
  1366. {}
  1367. {    ****************************************************    }
  1368. procedure CDGraphic.Hilite (aState: integer);
  1369.     var
  1370.         aRect: Rect;
  1371.  
  1372.     begin
  1373.         if state <> aState then begin
  1374.             state := aState;
  1375.             aRect := Frame;
  1376.             InvertRect(aRect);
  1377.         end; {IF state <> aState}
  1378.     end; {Hilite}
  1379.  
  1380.  
  1381. {    ****************************************************    }
  1382. {    C D I C O N    M E T H O D S                                                                                    }
  1383. {    ****************************************************    }
  1384. {    IDIcon                                                                                                                    }
  1385. {}
  1386. {        Initialize a CDIcon.                                                                                                }
  1387. {}
  1388. {    ****************************************************    }
  1389. procedure CDIcon.IDIcon (anEnclosure: CView;
  1390.                                 aSupervisor: CBureaucrat;
  1391.                                 aWidth: integer;
  1392.                                 aHeight: integer;
  1393.                                 aHEncl: integer;
  1394.                                 aVEncl: integer;
  1395.                                 aHSizing: SizingOption;
  1396.                                 aVSizing: SizingOption;
  1397.                                 anIconID: integer);
  1398.     begin
  1399.         IPane(anEnclosure, aSupervisor, aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing);
  1400.         theIcon := nil;
  1401.         NewIcon(anIconID);
  1402.     end; {IDIcon}
  1403.  
  1404.  
  1405. {    ****************************************************    }
  1406. {    Free                                                                                                                        }
  1407. {}
  1408. {        Free a CDIcon.                                                                                                    }
  1409. {}
  1410. {    ****************************************************    }
  1411. procedure CDIcon.Free;
  1412.     begin
  1413.         if theIcon <> nil then
  1414.             ReleaseResource(Handle(theIcon));
  1415.  
  1416.         inherited Free;
  1417.     end;
  1418. {    ****************************************************    }
  1419. {    Draw                                                                                                                    }
  1420. {}
  1421. {        Draw a CDIcon.                                                                                                    }
  1422. {}
  1423. {    ****************************************************    }
  1424. procedure CDIcon.Draw (var area: Rect);
  1425.     var
  1426.         aRect: Rect;
  1427.  
  1428.     begin
  1429.         aRect := frame;
  1430.         LoadResource(theIcon);
  1431.         PlotIcon(aRect, theIcon);
  1432.     end; {Draw}
  1433.  
  1434.  
  1435. {    ****************************************************    }
  1436. {    NewIcon}
  1437. {}
  1438. {        Specify a new ICON id.                                                                                        }
  1439. {}
  1440. {    ****************************************************    }
  1441. procedure CDIcon.NewIcon (anIconID: integer);
  1442.     begin
  1443.         if theIcon <> nil then
  1444.             ReleaseResource(Handle(theIcon));
  1445.  
  1446.         clickCmd := anIconID;
  1447.         theIconID := anIconID;
  1448.         theIcon := GetIcon(theIconID);
  1449.         CheckResource(theIcon);
  1450.         Refresh;
  1451.     end; {NewIcon}
  1452.  
  1453.  
  1454. {    ****************************************************    }
  1455. {    C D P I C T U R E    M E T H O D S                                                                            }
  1456. {    ****************************************************    }
  1457. {    IDPicture                                                                                                                }
  1458. {}
  1459. {        Initialize a CDPicture.                                                                                        }
  1460. {}
  1461. {    ****************************************************    }
  1462. procedure CDPicture.IDPicture (anEnclosure: CView;
  1463.                                 aSupervisor: CBureaucrat;
  1464.                                 aWidth: integer;
  1465.                                 aHeight: integer;
  1466.                                 aHEncl: integer;
  1467.                                 aVEncl: integer;
  1468.                                 aHSizing: SizingOption;
  1469.                                 aVSizing: SizingOption;
  1470.                                 aPictID: integer);
  1471.     begin
  1472.         IPane(anEnclosure, aSupervisor, aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing);
  1473.         thePicture := nil;
  1474.         NewPicture(aPictID);
  1475.     end; {IDPicture}
  1476.  
  1477.  
  1478. {    ****************************************************    }
  1479. {    Free                                                                                                                        }
  1480. {}
  1481. {        Free a CDPicture.                                                                                                }
  1482. {}
  1483. {    ****************************************************    }
  1484. procedure CDPicture.Free;
  1485.     begin
  1486.         if thePicture <> nil then
  1487.             ReleaseResource(Handle(thePicture));
  1488.  
  1489.         inherited Free;
  1490.     end;
  1491.  
  1492.  
  1493. {    ****************************************************    }
  1494. {    Draw                                                                                                                    }
  1495. {}
  1496. {        Draw a CDPicture.                                                                                                }
  1497. {}
  1498. {    ****************************************************    }
  1499. procedure CDPicture.Draw (var area: Rect);
  1500.     var
  1501.         aRect: Rect;
  1502.  
  1503.     begin
  1504.         aRect := frame;
  1505.         LoadResource(Handle(thePicture));
  1506.         DrawPicture(thePicture, aRect);
  1507.     end; {Draw}
  1508.  
  1509.  
  1510. {    ****************************************************    }
  1511. {    NewPicture}
  1512. {}
  1513. {        Specify a new PICT id.                                                                                        }
  1514. {}
  1515. {    ****************************************************    }
  1516. procedure CDPicture.NewPicture (aPictID: integer);
  1517.     begin
  1518.         if thePicture <> nil then
  1519.             ReleaseResource(Handle(thePicture));
  1520.  
  1521.         clickCmd := aPictID;
  1522.         thePictID := aPictID;
  1523.         thePicture := GetPicture(thePictID);
  1524.         CheckResource(Handle(thePicture));
  1525.         Refresh;
  1526.     end; {NewPicture}
  1527.  
  1528.  
  1529. {    ****************************************************    }
  1530. {    C D U S E R    M E T H O D S                                                                                    }
  1531. {    ****************************************************    }
  1532. {    IDUser                                                                                                                    }
  1533. {}
  1534. {        Initialize a CDUser.                                                                                            }
  1535. {}
  1536. {    ****************************************************    }
  1537. procedure CDUser.IDUser (anEnclosure: CView;
  1538.                                 aSupervisor: CBureaucrat;
  1539.                                 aWidth: integer;
  1540.                                 aHeight: integer;
  1541.                                 aHEncl: integer;
  1542.                                 aVEncl: integer;
  1543.                                 aHSizing: SizingOption;
  1544.                                 aVSizing: SizingOption);
  1545.     begin
  1546.         IPane(anEnclosure, aSupervisor, aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing);
  1547.     end; {IDUser}
  1548.  
  1549.  
  1550. {    ****************************************************    }
  1551. {    Hilite                                                                                                                    }
  1552. {}
  1553. {        Hilite a CDUser.                                                                                                    }
  1554. {}
  1555. {    ****************************************************    }
  1556. procedure CDUser.Hilite (aState: integer);
  1557.     begin
  1558.     end; {Hilite}
  1559.  
  1560.  
  1561. {    ****************************************************    }
  1562. {    C D E D I T T E X T    M E T H O D S                                                                            }
  1563. {    ****************************************************    }
  1564. procedure CDEditText.IDEditText (                                                        { Same parameters as CEditText }
  1565.                                 anEnclosure: CView;
  1566.                                 aSupervisor: CBureaucrat;
  1567.                                 aWidth, aHeight, aHEncl, aVEncl: integer;
  1568.                                 aHSizing, aVSizing: SizingOption;
  1569.                                 aLineWidth: integer);
  1570.     begin
  1571.         IEditText(anEnclosure, aSupervisor, aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing, aLineWidth);
  1572.  
  1573.         clickCmd := cmdNull;
  1574.         filter := 0;
  1575.         maxLength := 0;
  1576.     end;
  1577.  
  1578.  
  1579. {    ****************************************************    }
  1580. {    DoCommand                                                                                                            }
  1581. {}
  1582. {        Do a command.  Watches for paste commands that cause text to grow beyond        }
  1583. {        "maxLength" bytes.                                                                                            }
  1584. {}
  1585. {    ****************************************************    }
  1586. procedure CDEditText.DoCommand (theCommand: longint);
  1587.     begin
  1588.         inherited DoCommand(theCommand);
  1589.  
  1590.         if theCommand = cmdPaste then begin
  1591.             { Pasting avoids the length editing done in DoKeyDown; catch it here.}
  1592.             if (maxLength > 0) & (macTE^^.teLength > maxLength) then begin        { Unhealthy growth? }
  1593.                 with macTE^^ do begin
  1594.                     selStart := teLength - (teLength - maxLength);
  1595.                     selEnd := teLength;
  1596.                 end;
  1597.                 TEDelete(macTE);                                                                                { Surgically remove }
  1598.                 AdjustBounds;
  1599.                 ScrollToSelection;
  1600.             end; { IF teLength > maxLength }
  1601.  
  1602.             { Pasting avoids the character-by-character editing done in DoKeyDown.}
  1603.             if filter <> 0 then begin
  1604.                 {This is going to be messy once I get around to it.}
  1605.             end; {IF filter <> 0}
  1606.         end; { IF theCommand = cmdPaste }
  1607.  
  1608.         if (theCommand >= cmdUndo) & (theCommand <= cmdClear) & (clickCmd <> cmdNull) then
  1609.             itsSupervisor.DoCommand(clickCmd);                                    { Issue the appropriate command    }
  1610.  
  1611.     end;
  1612.  
  1613.  
  1614. {    ****************************************************    }
  1615. {    DoClick                                                                                                                    }
  1616. {}
  1617. {        Handle click on an CDEditText item.                                                                    }
  1618. {}
  1619. {    ****************************************************    }
  1620. procedure CDEditText.DoClick (                            { Handle clicks }
  1621.                                 hitPt: Point;                            { Mouse location in Frame coords }
  1622.                                 modifierKeys: integer;            { State of modifier keys }
  1623.                                 when: longint);                        { Tick time of mouse click }
  1624.     begin
  1625.         CDlog(itsSupervisor).ActivateThisTE(self);
  1626.         inherited DoClick(hitPt, modifierKeys, when);
  1627.         if clickCmd <> cmdNull then                            { Issue the appropriate command    }
  1628.             itsSupervisor.DoCommand(clickCmd);
  1629.     end;
  1630.  
  1631.  
  1632. {    ****************************************************    }
  1633. {    SetClickCmd                                                                                                            }
  1634. {}
  1635. {        Specify the command which is sent to a CDEditText's supervisor                        }
  1636. {        after a confirmed click.                                                                                        }
  1637. {}
  1638. {    ****************************************************    }
  1639. procedure CDEditText.SetClickCmd (                    { Set command to issue upon click }
  1640.                                 aClickCmd: longint);                { Specified command number }
  1641.  
  1642.     begin
  1643.         clickCmd := aClickCmd;
  1644.     end;
  1645.  
  1646.  
  1647. {    ****************************************************    }
  1648. {    DoKeyDown                                                                                                            }
  1649. {}
  1650. {        Handle special keys before TextEdit sees them.                                                    }
  1651. {}
  1652. {    ****************************************************    }
  1653. procedure CDEditText.DoKeyDown (                    { Handle key-down }
  1654.                                 theChar: char;                        { Key character }
  1655.                                 keyCode: Byte;                        { Key code }
  1656.                                 macEvent: EventRecord);        { Mac event record }
  1657.  
  1658. {    filter is a field that controls optional behavior.  The field is set by adding a set of constants:}
  1659. {}
  1660. { CdCrOkOff        (2) means CR <> item 1}
  1661. {}
  1662. { CdEtxOkOff        (4) means ETX <> item 1}
  1663. {}
  1664. { CdEscOff            (8) means ESC <> item 2}
  1665. {}
  1666. { CdCrFiltOn        (16) means filter (prevent) CR.}
  1667. {}
  1668. { CdSpecFiltOn    (32) means filter (prevent) all other special, except HT, BS, and}
  1669. {                        the arrow keys, which have editing uses with TE.}
  1670. {}
  1671. { CdNspFiltOn    (64) means filter (prevent) all characters that are invalid as}
  1672. {                        part of NSP keyword names, except HT, BS, and the arrow}
  1673. {                        keys, which have editing uses with TE.}
  1674. {}
  1675. {}
  1676. { CdClidFiltOn    (128) means filter (prevent) all characters that are invalid as}
  1677. {                        part of client ids, and uppercase input.}
  1678. {}
  1679. { CdLenFiltOn        (256) means apply the length check; prevent field from growing}
  1680. {                        beyond "maxLength" bytes.}
  1681. {}
  1682. { CdCMSFiltOn    (512) means filter (prevent) all characters that are not alphabetic}
  1683. {                        or numeric, and uppercase lowercase characters. (Intended}
  1684. {                        for CMS filenames)}
  1685. {}
  1686. { CdNumFiltOn    (1024) means filter (prevent) all characters that are not numeric.}
  1687. {}
  1688. { CdUpDownOn    (2048) means treat up and down arrow keys as commands.}
  1689. {}
  1690. { CdLeftRightOn    (4096) means treat left and right arrow keys as commands.}
  1691. {}
  1692. {    Read the above descriptions carefully; some are "negative" flags}
  1693. {    (meaning that turning the bit on prevents some action), and some}
  1694. {    are positive (meaning that turning the bit on causes some action).}
  1695. {}
  1696. {    For example, if you DON'T want CR to mean "click on item 1", and}
  1697. {    you DO want CR filtered, you would "SetEdit(CdCrOkOff+CdCrFiltOn);"}
  1698. {}
  1699. {    If features conflict, the processing basically occurs in the order}
  1700. {    they are listed above.}
  1701. {}
  1702. {    Set filter to 0 to get the default editing.}
  1703. {}
  1704.     const
  1705.         ETX = $03;
  1706.         HT = $09;
  1707.         CR = $0D;
  1708.         ESC = $1B;
  1709.         LKEY = $1C;
  1710.         RKEY = $1D;
  1711.         UKEY = $1E;
  1712.         DKEY = $1F;
  1713.  
  1714.         crOkMask = $02;            {        Negative: feature OFF if bit set}
  1715.         etxOkMask = $04;            {        Negative: feature OFF if bit set}
  1716.         escCanMask = $08;        {        Negative: feature OFF if bit set}
  1717.         crFiltMask = $10;            {#1    Positive: feature ON if bit set}
  1718.         specFiltMask = $20;        {#1    Positive: feature ON if bit set}
  1719.         nspFiltMask = $40;        {#1    Positive: feature ON if bit set}
  1720.         clidFiltMask = $80;        {#1    Positive: feature ON if bit set}
  1721.         lenFiltMask = $100;        {#2    Positive: feature ON if bit set}
  1722.         CMSFiltMask = $200;    {#1    Positive: feature ON if bit set}
  1723.         NumFiltMask = $400;    {#1    Positive: feature ON if bit set}
  1724.         VertMask = $800;            {#3    Positive: feature ON if bit set}
  1725.         HorizMask = $1000;        {#3    Positive: feature ON if bit set}
  1726. {}
  1727. {        1) For the items marked by #1, the program returns command}
  1728. {            "cmdBadChar" to the program when it filters a character.}
  1729. {}
  1730. {        2) For the items marked by #2, the program returns command}
  1731. {            "cmdBadLength" to the program when it filters a character.}
  1732. {}
  1733. {        3) For the items marked by #3, the program returns command}
  1734. {            "cmdArrowLeft, cmdArrowRight, cmdArrowUp, or cmdArrowDown"}
  1735. {            to the program when it detects the the correspoding arrow key.}
  1736. {}
  1737. {        The positive features are tested against the filter;}
  1738. {        the negative features are tested against the NOT of the filter (notFilter).}
  1739. {}
  1740.     type
  1741.         Char4 = packed record                                {Useful for accessing ...}
  1742.                 case integer of
  1743.                     0: (
  1744.                             chr3, chr2, chr1, chr0: char    {chars within a longint}
  1745.                     );
  1746.                     1: (
  1747.                             int1, int0: integer                        {int's within a longint}
  1748.                     );
  1749.             end;
  1750.     var
  1751.         cmd: longint;
  1752.  
  1753.         notFilter: integer;
  1754.  
  1755.     begin
  1756.         cmd := 0;
  1757.         notFilter := BNOT(filter);
  1758.  
  1759.         {Uppercase characters in CdCMSFiltOn or CdClidFiltOn case}
  1760.         if ((BAnd(CMSFiltMask, filter) <> 0) | (BAnd(ClidFiltMask, filter) <> 0)) & (Ord(theChar) in [$61..$7A]) then begin
  1761.             { Uppercase a lowercase character }
  1762.             theChar := Chr(Ord(theChar) - 32);                        { Uppercase it }
  1763.             Char4(macEvent.message).Chr0 := theChar;            { Put it in event }
  1764.         end; {CMSFiltMask or ClidFiltMask and lowercase character}
  1765.  
  1766.         {Check for special characters}
  1767.         if (BAnd(HorizMask, filter) <> 0) & (Ord(theChar) in [LKEY..RKEY]) then
  1768.             { Filter arrow keys }
  1769.             cmd := cmdArrowLeft + Ord(theChar) - LKEY        { Inform caller }
  1770.  
  1771.         else if (BAnd(VertMask, filter) <> 0) & (Ord(theChar) in [UKEY..DKEY]) then
  1772.             { Filter arrow keys }
  1773.             cmd := cmdArrowLeft + Ord(theChar) - LKEY        { Inform caller }
  1774.  
  1775.         else if (BAnd(crOkMask, notFilter) <> 0) and (Ord(theChar) = CR) then
  1776.             { Return = OK }
  1777.             cmd := cmdOkEquiv
  1778.                                                                 { Simulate clicking OK }
  1779.  
  1780.         else if (BAnd(etxOkMask, notFilter) <> 0) and (Ord(theChar) = ETX) then
  1781.             { Enter = OK }
  1782.             cmd := cmdOkEquiv                                                                { Simulate clicking OK }
  1783.  
  1784.         else if (BAnd(escCanMask, notFilter) <> 0) and (Ord(theChar) = ESC) then
  1785.             { ESC = CANCEL }
  1786.             cmd := cmdCancelEquiv                                                    { Simulate clicking Cancel }
  1787.  
  1788.         else if (BAnd(crFiltMask, filter) <> 0) and (Ord(theChar) = CR) then
  1789.             { Filter CR }
  1790.             cmd := cmdBadChar                                                { Note bad character }
  1791.  
  1792.         else if (BAnd(specFiltMask, filter) <> 0) & (not (Ord(theChar) in [$08..$09, $0D, $1C..$1F, $20, $21, $23..$7E])) then
  1793.             { Filter characters disallowed in this context }
  1794.             cmd := cmdBadChar                                                { Note bad character }
  1795.  
  1796.         else if (BAnd(nspFiltMask, filter) <> 0) & (not (Ord(theChar) in [$08..$09, $0D, $1C..$1F, $30..$39, $41..$5A, $61..$7A])) then
  1797.             { Filter characters disallowed in this context }
  1798.             cmd := cmdBadChar                                                { Note bad character }
  1799.  
  1800.         else if (BAnd(clidFiltMask, filter) <> 0) & (not (Ord(theChar) in [$08..$09, $0D, $1C..$1F, $24, $41..$5A])) then
  1801.             { Filter characters disallowed in this context }
  1802.             cmd := cmdBadChar                                                { Note bad character }
  1803.  
  1804.         else if (BAnd(CMSFiltMask, filter) <> 0) & (not (Ord(theChar) in [$08..$09, $0D, $1C..$1F, $24, $30..$39, $41..$5A])) then
  1805.             { Filter characters disallowed in this context }
  1806.             cmd := cmdBadChar                                                { Note bad character }
  1807.  
  1808.         else if (BAnd(numFiltMask, filter) <> 0) & (not (Ord(theChar) in [$08..$09, $0D, $1C..$1F, $30..$39])) then
  1809.             { Filter characters disallowed in this context }
  1810.             cmd := cmdBadChar                                                { Note bad character }
  1811.  
  1812.         else if (BAnd(lenFiltMask, filter) <> 0) & (not (Ord(theChar) in [$08..$09, $0D, $1C..$1F])) then
  1813.             {Check length}
  1814.             with macTE^^ do
  1815.                 if (selStart = selEnd) and (teLength = maxLength) then
  1816.                     cmd := cmdBadLength;                                    { Note too many characters }
  1817.  
  1818.  
  1819.         if cmd <> 0 then
  1820.             DoCommand(cmd)
  1821.  
  1822.         { One more special character to check for... }
  1823.         else if (theChar = Chr(HT)) then
  1824.             if (BAnd(macEvent.modifiers, shiftKey) <> 0) then            { Shift - tab }
  1825.                 CDlog(itsSupervisor).ActivatePrevTE
  1826.             else                                                                                    { Tab }
  1827.                 CDlog(itsSupervisor).ActivateNextTE
  1828.  
  1829.         else begin
  1830.             inherited DoKeyDown(theChar, keyCode, macEvent);        { Everything else}
  1831.             if clickCmd <> cmdNull then                                                { Issue the appropriate command    }
  1832.                 itsSupervisor.DoCommand(clickCmd);
  1833.         end;
  1834.     end;
  1835.  
  1836.  
  1837. {    ****************************************************    }
  1838. {    SetSelect                                                                                                                }
  1839. {}
  1840. {        Set the selection range for a CDEditText item.                                                    }
  1841. {}
  1842. {    ****************************************************    }
  1843. procedure CDEditText.SetSelect (                        { Set selection range }
  1844.                                 start: longint;                        { Start of selection range }
  1845.                                 stop: longint);                        { End of selection range }
  1846.     begin
  1847.         TESetSelect(start, stop, macTE);
  1848.     end;
  1849.  
  1850.  
  1851. {    ****************************************************    }
  1852. {    SetEdit                                                                                                                    }
  1853. {}
  1854. {        Set the filter and maxLength fields for a CDEditText item.                                    }
  1855. {}
  1856. {    ****************************************************    }
  1857. procedure CDEditText.SetEdit (                                                { Set editing control variables }
  1858.                                 aFilter: integer;                                        { The filter mask }
  1859.                                 aMaxLength: integer);                                { The maximum length }
  1860.     begin
  1861.         filter := aFilter;
  1862.         maxLength := aMaxLength;
  1863.     end;
  1864.  
  1865.  
  1866. {    ****************************************************    }
  1867. {    C T I T L E D B O R D E R   M E T H O D S                                                                    }
  1868. {    ****************************************************    }
  1869. procedure CTitledBorder.ITitledBorder (anEnclosure: CView;
  1870.                                 aSupervisor: CBureaucrat;
  1871.                                 aWidth, aHeight, aHEncl, aVEncl: integer;
  1872.                                 aHSizing, aVSizing: SizingOption;
  1873.                                 aTitle: Str255);
  1874.     begin
  1875.         IBorder(anEnclosure, aSupervisor, aWidth, aHeight, aHEncl, aVEncl, aHSizing, aVSizing);
  1876.         itsTitle := Concat(' ', aTitle, ' ');
  1877.         txFont := macPort^.txFont;
  1878.         txFace := macPort^.txFace;
  1879.         txMode := macPort^.txMode;
  1880.         txSize := macPort^.txSize;
  1881.     end;
  1882.  
  1883.  
  1884. procedure CTitledBorder.SetTitle (aTitle: Str255);
  1885.     var
  1886.         theRect: Rect;
  1887.         theFontInfo: FontInfo;
  1888.  
  1889.     begin
  1890.         Prepare;
  1891.         TextFont(txFont);        { Set grafport's text characteristics }
  1892.         TextFace(txFace);
  1893.         TextSize(txSize);
  1894.         GetFontInfo(theFontInfo);
  1895.  
  1896.         theRect := frame;
  1897.         with theRect, theFontInfo do
  1898.             bottom := top + ascent + descent + leading;
  1899.         RefreshRect(theRect);
  1900.  
  1901.         itsTitle := Concat(' ', aTitle, ' ');
  1902.     end;
  1903.  
  1904.  
  1905. procedure CTitledBorder.Draw (var area: Rect);
  1906.     var
  1907.         r: Rect;
  1908.         aStr: Str255;
  1909.         aFontInfo: FontInfo;
  1910.  
  1911.     begin
  1912.         TextFont(txFont);        { Set grafport's text characteristics }
  1913.         TextFace(txFace);
  1914.         TextSize(txSize);
  1915.         GetFontInfo(aFontInfo);
  1916.  
  1917.         r := frame;
  1918.  
  1919.         if itsTitle <> '' then
  1920.             r.top := r.top + aFontInfo.ascent div 2;
  1921.  
  1922.         r.right := r.right - dropShadow;
  1923.         r.bottom := r.bottom - dropShadow;
  1924.         PenNormal;
  1925.         PenSize(thickness, thickness);
  1926.         FrameRect(r);
  1927.  
  1928.         if dropShadow > 0 then begin
  1929.             PenSize(dropShadow, dropShadow);
  1930.             MoveTo(frame.left + dropShadow, frame.bottom - dropShadow);
  1931.             LineTo(frame.right - dropShadow, frame.bottom - dropShadow);
  1932.             LineTo(frame.right - dropShadow, frame.top + dropShadow);
  1933.         end;
  1934.  
  1935.         if itsTitle <> '' then begin
  1936.             MoveTo(frame.left + BORDER_OFFSET + BORDER_OFFSET, frame.top + aFontInfo.ascent);
  1937.             aStr := itsTitle;
  1938.             TextMode(srcCopy);
  1939.             DrawString(aStr);
  1940.             TextMode(txMode);
  1941.         end;
  1942.     end;
  1943.  
  1944.  
  1945. {    ****************************************************    }
  1946. {    C D R A D I O G R O U P   M E T H O D S                                                                    }
  1947. {    ****************************************************    }
  1948. {    IDRadioGroup}
  1949. {}
  1950. {        Initialize a CDRadioGroup object}
  1951. {}
  1952. {    ****************************************************    }
  1953. procedure CDRadioGroup.IDRadioGroup (anEnclosure: CView;
  1954.                                 aSupervisor: CBureaucrat;
  1955.                                 aTitle: Str255);
  1956.  
  1957.     begin
  1958.         IBureaucrat(aSupervisor);        { Initialize superclass                }
  1959.         new(itsButtons);                    { Create cluster for storing            }
  1960.         itsButtons.ICluster;                {   buttons belonging to the group    }
  1961.         station := nil;                    { No station is selected yet            }
  1962.  
  1963.         new(itsBorder);
  1964.         itsBorder.ITitledBorder(anEnclosure, aSupervisor, 0, 0, 0, 0, sizFIXEDLEFT, sizFIXEDTOP, aTitle);
  1965.     end;
  1966.  
  1967.  
  1968. {    ****************************************************    }
  1969. {    Free  (OVERRIDE)}
  1970. {}
  1971. {        Dispose of a RadioGroup object.}
  1972. {}
  1973. {    ****************************************************    }
  1974. procedure CDRadioGroup.Free;
  1975.     begin
  1976.         itsButtons.Free;
  1977.         inherited Free;
  1978.     end;
  1979.  
  1980.  
  1981. {    ****************************************************    }
  1982. {    AddButton}
  1983. {}
  1984. {        Add a RadioButton to the group}
  1985. {}
  1986. {    ****************************************************    }
  1987. procedure CDRadioGroup.AddButton (theRadioButton: CDRadioButton);
  1988.     begin
  1989.         itsButtons.Add(theRadioButton);
  1990.     end;
  1991.  
  1992.  
  1993. {    ****************************************************    }
  1994. {    RemoveButton}
  1995. {}
  1996. {        Remove a RadioButton from the group}
  1997. {}
  1998. {    ****************************************************    }
  1999. procedure CDRadioGroup.RemoveButton (theRadioButton: CDRadioButton);
  2000.     begin
  2001.         itsButtons.Remove(theRadioButton);
  2002.     end;
  2003.  
  2004.  
  2005. {    ****************************************************    }
  2006. {    ChangeStation}
  2007. {}
  2008. {        Change the current station}
  2009. {}
  2010. {    ****************************************************    }
  2011. procedure CDRadioGroup.ChangeStation (theStation: CDRadioButton);
  2012.     begin
  2013.         if station <> nil then
  2014.             station.SetValue(BUTTON_OFF);
  2015.         station := theStation;
  2016.         station.SetValue(BUTTON_ON);
  2017.     end;
  2018.  
  2019.  
  2020. {    ****************************************************    }
  2021. {    GetStation}
  2022. {}
  2023. {        Return the current station}
  2024. {}
  2025. {    ****************************************************    }
  2026. function CDRadioGroup.GetStation: CDRadioButton;
  2027.     begin
  2028.         GetStation := station;
  2029.     end;
  2030.  
  2031.  
  2032. {    ****************************************************    }
  2033. {    SetStationID}
  2034. {}
  2035. {        Set the current station, specified by an ID number}
  2036. {}
  2037. {    ****************************************************    }
  2038. function Test_StationID (theRadioButton: CDRadioButton;
  2039.                                 theID: Ptr): Boolean;
  2040.     begin
  2041.         Test_StationID := theRadioButton.GetIdNumber = IntPtr(theID)^;
  2042.     end;
  2043.  
  2044.  
  2045. procedure CDRadioGroup.SetStationID (aStationID: integer);
  2046.     var
  2047.         newStation: CDRadioButton;
  2048.  
  2049.     begin
  2050.         if station <> nil then
  2051.             if station.GetIdNumber <> aStationID then
  2052.                 station.SetValue(BUTTON_OFF);
  2053.  
  2054.         newStation := CDRadioButton(itsButtons.FindItem1(Test_StationID, @aStationID));
  2055.  
  2056.         if newStation <> nil then begin
  2057.             station := newStation;
  2058.             station.SetValue(BUTTON_ON);
  2059.         end;
  2060.     end;
  2061.  
  2062.  
  2063. {    ****************************************************    }
  2064. {    GetStationID}
  2065. {}
  2066. {        Return the current station's ID number}
  2067. {}
  2068. {    ****************************************************    }
  2069. function CDRadioGroup.GetStationID: integer;
  2070.     begin
  2071.         if station = nil then
  2072.             GetStationID := NO_STATION
  2073.         else
  2074.             GetStationID := station.GetIdNumber
  2075.     end;
  2076.  
  2077. procedure CDRadioGroup.SetBorderTitle (aStr: Str255);
  2078.     begin
  2079.         itsBorder.SetTitle(aStr);
  2080.     end;
  2081.  
  2082. procedure CDRadioGroup.CalcBorder (aWidth, aHeight: integer);
  2083.     var
  2084.         theFrame: Rect;
  2085.         aRect: Rect;
  2086.         index: integer;
  2087.         aFontInfo: FontInfo;
  2088.         hOrigin: longint;
  2089.         vOrigin: longint;
  2090.  
  2091.     begin
  2092.         SectPanes(itsButtons, 1, itsButtons.GetNumItems, theFrame);
  2093.  
  2094.         GetFontInfo(aFontInfo);
  2095.         with aFontInfo do
  2096.             theFrame.top := theFrame.top - (ascent + descent + leading);
  2097.  
  2098.         InsetRect(theFrame, -BORDER_OFFSET, -BORDER_OFFSET);
  2099.  
  2100.         with theFrame do begin
  2101.             if aWidth <> 0 then
  2102.                 right := left + aWidth;
  2103.             if aHeight <> 0 then
  2104.                 bottom := top + aHeight;
  2105.         end; {WITH theFrame}
  2106.  
  2107.     {    Determine the difference between the new frame and the old frame.    }
  2108.         itsBorder.Refresh;
  2109.         itsBorder.GetFrame(aRect);
  2110.         with aRect do begin
  2111.             left := theFrame.left - left;
  2112.             top := theFrame.top - top;
  2113.             right := theFrame.right - right;
  2114.             bottom := theFrame.bottom - bottom;
  2115.         end;
  2116.  
  2117.     {    Change the size and location of the frame.    }
  2118.         itsBorder.ChangeSize(aRect, FALSE);
  2119.         itsBorder.Place(theFrame.left, theFrame.top, TRUE);
  2120.     end;
  2121.  
  2122.  
  2123. {    ****************************************************    }
  2124. {    C D M O D A L D E S K T O P    M E T H O D S                                                            }
  2125. {    ****************************************************    }
  2126. {     DispatchClick {OVERRIDE) }
  2127. {}
  2128. {            Respond to a mouse down. Determine where the mouse down occurred }
  2129. {            and send the appropriate messages to the affected objects. The }
  2130. {            where field of macEvent is in Global coordinates. }
  2131. {}
  2132. {    ****************************************************    }
  2133. procedure CDModalDeskTop.DispatchClick (var macEvent: EventRecord);
  2134.     var
  2135.         thePart: integer;                { Location of mouse click }
  2136.         macWindow: WindowPtr;    { Window where click occurred }
  2137.         theWindow: CWindow;        { Corresponding window object }
  2138.         menuChoice: longint;            { Selection from a menu }
  2139.         modal: boolean;                    { FrontMost window is modal }
  2140.         theTop: CWindow;            { Top Window (9/25/90        J. Cardinal    Modal Support) }
  2141.  
  2142.     begin
  2143.         theTop := GetTopWindow;                                { 9/25/90        J. Cardinal    Modal Support }
  2144.         if Member(theTop, CDlogWind) then                { 9/25/90        J. Cardinal    Modal Support }
  2145.             modal := CDlogWind(theTop).GetModal        { 9/25/90        J. Cardinal    Modal Support }
  2146.         else                                                                { 9/25/90        J. Cardinal    Modal Support }
  2147.             modal := FALSE;                                        { 9/25/90        J. Cardinal    Modal Support }
  2148.  
  2149.         thePart := FindWindow(macEvent.where, macWindow);
  2150.         if (macWindow <> nil) & (thePart <> inSysWindow) then
  2151.             theWindow := CWindow(GetWRefCon(macWindow));
  2152.  
  2153.         if modal & (theWindow <> theTop) then begin        { 9/25/90        J. Cardinal    Modal Support }
  2154.             if thePart <> inMenuBar then begin                    { 9/25/90        J. Cardinal    Modal Support }
  2155.                 SysBeep(1);                                                    { 9/25/90        J. Cardinal    Modal Support }
  2156.                 Exit(DispatchClick);                                        { 9/25/90        J. Cardinal    Modal Support }
  2157.             end;                                                                    { 9/25/90        J. Cardinal    Modal Support }
  2158.         end;                                                                        { 9/25/90        J. Cardinal    Modal Support }
  2159.  
  2160.         case thePart of
  2161.  
  2162.             inDesk: 
  2163.                 begin
  2164.                 CountClicks(SELF, macEvent);
  2165.                 DoClick(macEvent.where, macEvent.modifiers, macEvent.when);
  2166.             end;
  2167.  
  2168.             inMenuBar: 
  2169.                 begin
  2170.                 gBartender.UpdateAllMenus;
  2171.                 menuChoice := MenuSelect(macEvent.where);
  2172.                 if HiWord(menuChoice) <> 0 then begin
  2173.                     gGopher.DoCommand(gBartender.FindCmdNumber(HiWord(menuChoice), LoWord(menuChoice)));
  2174.                     HiliteMenu(0);
  2175.                 end;
  2176.             end;
  2177.  
  2178.             inSysWindow: 
  2179.                 SystemClick(macEvent, macWindow);
  2180.  
  2181.             inContent: 
  2182.                 begin
  2183.                 if (not theWindow.active) | (theWindow.floating & (WindowPtr(macWindow) <> FrontWindow)) then begin
  2184.                     theWindow.Select;
  2185.                     if not theWindow.actClick then
  2186.                         Exit(DispatchClick)
  2187.                     else
  2188.                         theWindow.Activate;
  2189.                 end;
  2190.                 if theWindow.wantsClicks then begin
  2191.                     UpdateWindows;
  2192.                     theWindow.DispatchClick(macEvent);
  2193.                 end
  2194.                 else begin
  2195.                     CountClicks(SELF, macEvent);
  2196.                     DoClick(macEvent.where, macEvent.modifiers, macEvent.when);
  2197.                 end;
  2198.             end;
  2199.  
  2200.             inDrag: 
  2201.                 theWindow.Drag(macEvent);
  2202.  
  2203.             inGrow: 
  2204.                 theWindow.Resize(macEvent);
  2205.  
  2206.             inGoAway: 
  2207.                 if TrackGoAway(macWindow, macEvent.where) then
  2208.                     theWindow.Close;
  2209.  
  2210.             inZoomIn, inZoomOut: 
  2211.                 if TrackBox(macWindow, macEvent.where, thePart) then
  2212.                     theWindow.Zoom(thePart);
  2213.         end;
  2214.     end;
  2215.  
  2216.  
  2217. {    ****************************************************    }
  2218. {    C D D L O G W I N D    M E T H O D S                                                                        }
  2219. {    ****************************************************    }
  2220. {    IDlogWind                                                                                                                }
  2221. {}
  2222. {        Initialize a DlogWind object.                                                                                }
  2223. {}
  2224. {        Copied from CWindow source, changing WIND to DLOG, and adding DLOG                }
  2225. {        template definition.                                                                                            }
  2226. {}
  2227. {    ****************************************************    }
  2228. procedure CDlogWind.IDlogWind (DLOGid: integer;
  2229.                                 aFloating: Boolean;
  2230.                                 anEnclosure: CDesktop;
  2231.                                 aSupervisor: CDirector);
  2232.  
  2233.     var
  2234.         theDLOG: CDlogTemplateH;
  2235.         theDLOGP: CDlogTemplateP;
  2236.         saveVis: integer;
  2237.         behindWindow: WindowPtr;
  2238.  
  2239.     begin
  2240.         modal := FALSE;
  2241.  
  2242.         IView(anEnclosure, aSupervisor);        { Initialize superclass.    }
  2243.  
  2244. {             Because we maintain our own window list and have to do    }
  2245. {             a lot of manual activating/deactivating to support           }
  2246. {             floating windows, it is imperative that windows be          }
  2247. {             invisible when initially created. Therefore, we read the     }
  2248. {             the WIND resource template and set the visible flag to       }
  2249. {             FALSE (after saving the original value).                         }
  2250.  
  2251.         theDLOG := CDlogTemplateH(GetResource('DLOG', DLOGid));
  2252.         CheckResource(Handle(theDLOG));
  2253.         theDLOGP := theDLOG^;
  2254.         saveVis := theDLOGP^.visible;
  2255.         theDLOGP^.visible := 0;
  2256.  
  2257.         floating := aFloating;
  2258.  
  2259.         MakeMacWindow(DLOGid);
  2260.         SetWRefCon(macPort, longint(SELF));
  2261.  
  2262.         WindowPeek(macPort)^.windowKind := OBJ_WINDOW_KIND;
  2263.  
  2264.         sizeRect := GetGrayRgn^^.rgnBBox;
  2265.         sizeRect.left := MIN_WSIZE;
  2266.         sizeRect.top := MIN_WSIZE;
  2267.  
  2268.         actClick := FALSE;
  2269.         wantsClicks := TRUE;
  2270.  
  2271.         CDesktop(itsEnclosure).AddWind(SELF);
  2272.  
  2273.         if saveVis <> 0 then begin
  2274.             theDLOG := CDlogTemplateH(GetResource('DLOG', DLOGid));
  2275.             theDLOG^^.visible := 1;
  2276.             Select;
  2277.         end;
  2278.     end;
  2279.  
  2280.  
  2281. {    ****************************************************    }
  2282. {     MakeMacWindow                                                                                                    }
  2283. {}
  2284. {            Create a new Toolbox window record using the specified DLOG                        }
  2285. {            resource ID. This method creates a normal Mac window and lets                        }
  2286. {            the window manager allocate space for the window record. Subclasses            }
  2287. {            should override this method to perform their own memory allocation                }
  2288. {            or to create a color window. For compatibility with the Desktop                        }
  2289. {            class, the convention of putting floating windows in front and                            }
  2290. {            non-floating windows in back should be observed.                                            }
  2291. {}
  2292. {    ****************************************************    }
  2293. procedure CDlogWind.MakeMacWindow (WINDid: integer);
  2294.     var
  2295.         bottomWindow: CWindow;
  2296.         DLOGtmpl: CDlogTemplateH;
  2297.  
  2298.     begin
  2299.         DLOGtmpl := CDlogTemplateH(GetResource('DLOG', WINDid));
  2300.         CheckResource(Handle(DLOGtmpl));
  2301.  
  2302.         HLock(Handle(DLOGtmpl));
  2303.         with DLOGtmpl^^ do
  2304.             if floating then
  2305.                 macPort := NewWindow(nil, boundsRect, title, (visible <> 0), WDEFid, WindowPtr(-1), (goAwayFlag <> 0), refCon)
  2306.             else begin        { Put the window behind the application's bottom window, but     }
  2307.                     { in front of THINK Pascal's windows (if any).                         }
  2308.  
  2309.                 bottomWindow := gDesktop.GetBottomWindow;
  2310.                 if bottomWindow = nil then
  2311.                     macPort := NewWindow(nil, boundsRect, title, (visible <> 0), WDEFid, WindowPtr(-1), (goAwayFlag <> 0), refCon)
  2312.                 else
  2313.                     macPort := NewWindow(nil, boundsRect, title, (visible <> 0), WDEFid, bottomWindow.GetMacPort, (goAwayFlag <> 0), refCon);
  2314.             end;
  2315.         HUnlock(Handle(DLOGtmpl));
  2316.         ReleaseResource(Handle(DLOGtmpl));
  2317.     end;
  2318.  
  2319. function CDlogWind.GetModal: boolean;
  2320.     begin
  2321.         GetModal := modal;
  2322.     end;
  2323.  
  2324.  
  2325. procedure CDlogWind.SetModal (aModal: boolean);
  2326.     begin
  2327.         modal := aModal;
  2328.     end;
  2329.  
  2330.  
  2331. {    ****************************************************    }
  2332. {     C D L O G   M E T H O D S                                                                                        }
  2333. {    ****************************************************    }
  2334. {     IDlog                                                                                                                    }
  2335. {}
  2336. {        Until now, things have been fairly clean and simple.  It gets a little                        }
  2337. {        messy here, though things are still pretty simple:                                                }
  2338. {        1    Make a window, using info taken from a DLOG resource.                                    }
  2339. {        2    Initialize some instance variables (notably, lists of panes).                            }
  2340. {        3    Get the DITL resource, set pointer to first item, and loop over items:            }
  2341. {            3.0    Copy item from resource to local variable.                                            }
  2342. {            3.1    Clean up itemType, determine if item is enabled, etc.                                }
  2343. {            3.2    Make a new object based on itemType.                                                    }
  2344. {            3.4    Do some item-specific initialization.                                                        }
  2345. {            3.5    Advance pointer to next item.                                                                }
  2346. {        4    Activate first EditText field, if any.                                                                }
  2347. {}
  2348. {    ****************************************************    }
  2349. procedure CDlog.IDlog (DLOGid: integer;
  2350.                                 aFloating: Boolean;
  2351.                                 aDocument: CDocument;
  2352.                                 aSupervisor: CApplication;
  2353.                                 aFont: integer;
  2354.                                 aSize: integer);
  2355.  
  2356.     const
  2357.         itemButton = ctrlItem + btnCtrl;
  2358.         itemCheckbox = ctrlItem + chkCtrl;
  2359.         itemRadio = ctrlItem + radCtrl;
  2360.         itemControl = ctrlItem + resCtrl;
  2361.  
  2362.     var
  2363.         curPort: GrafPtr;                            {For save/restore of QuickDraw port}
  2364.  
  2365.         aDialog: CDlogWind;                        {The window for this dialog}
  2366.  
  2367.         DLOGtmpl: CDlogTemplateH;            {Handle to a DLOG resource}
  2368.         DITLtmpl: Handle;                            {Handle to a DITL resource}
  2369.         DITLPtr: Ptr;                                {Pointer INTO a DITL; points at "items"}
  2370.         nItems: integer;                            {Number of items in dialog}
  2371.         index: integer;                                {Controls loop over items in dialog}
  2372.         item: CDDitlItemRec;                        {A dialog item; see IM-I pg 427}
  2373.         itemType: integer;                        {Item type}
  2374.         itemLen: integer;                            {Item length}
  2375.         enabled: boolean;                            {TRUE if item enabled (handles clicks)}
  2376.  
  2377.         aPane: CPane;                                {A spare CPane used during item initialization}
  2378.  
  2379.         radioCount: integer;                        {Number of radio buttons in the current group}
  2380.                                                             {... if zero, we need to init an new group}
  2381.         radioGroup: CDRadioGroup;            {The current radio group, if any}
  2382.  
  2383.     begin
  2384.         inherited IDirector(aSupervisor);        {Initialize superclass}
  2385.  
  2386.         New(aDialog);                                                                {Make the dialog window.}
  2387.         PositionDlog('DLOG', DLOGid);                                        {Put it in preferred location}
  2388.         aDialog.IDlogWind(DLOGid, aFloating, gDesktop, self);        {Initialize the dialog window}
  2389.         itsWindow := aDialog;                                                    {Save window in instance variable}
  2390.  
  2391.         GetPort(curPort);                                    {Muck about to set text characteristics}
  2392.         SetPort(itsWindow.macPort);
  2393.         TextFont(aFont);
  2394.         TextSize(aSize);
  2395.         SetPort(curPort);
  2396.  
  2397.         {Initialize instance variables}
  2398.         itsDocument := aDocument;            {Save this in case dialog communicates with document}
  2399.         itsDlogID := DLOGid;                        {Save this for no clear reason... identifies DLOG?}
  2400.  
  2401.         new(itsPanes);                                {List of panes corresponding to DITL items}
  2402.         itsPanes.IList;
  2403.  
  2404.         new(itsTEPanes);                            {List of edit text panes}
  2405.         itsTEPanes.IList;
  2406.         itsActiveTE := 0;
  2407.  
  2408.         new(itsRadioGroups);                    {List of radio groups, which supervise the radio buttons}
  2409.         itsRadioGroups.IList;
  2410.  
  2411.         {Get the DITL id out of the DLOG resource, and then get the DITL resource.}
  2412.         DLOGtmpl := CDlogTemplateH(GetResource('DLOG', DLOGid));
  2413.         CheckResource(Handle(DLOGtmpl));
  2414.  
  2415.         DITLtmpl := GetResource('DITL', DLOGtmpl^^.itemsID);
  2416.         CheckResource(Handle(DITLtmpl));
  2417.         ReleaseResource(Handle(DLOGtmpl));            {Don't need DLOG anymore}
  2418.         HLock(Handle(DITLtmpl));                            {Lock it; we use a pointer into it (DITLPtr)}
  2419.  
  2420.         {Prepare to loop over the DITL}
  2421.         DITLPtr := DITLtmpl^;
  2422.         nItems := IntPtr(DITLPtr)^;                        {First thing in DITL is number of items - 1 (integer)}
  2423.         DITLPtr := Ptr(Ord4(DITLPtr) + 2);            {Push pointer past number of items}
  2424.  
  2425.         for index := 0 to nItems do begin
  2426.             BlockMove(DITLPtr, @item, SizeOf(item));                {Copy next item to the local variable}
  2427.             with item do begin
  2428.                 itemType := BAnd(BSR(typeLen, 8), $FF);                {Isolate itemType}
  2429.                 enabled := (BAnd(itemType, itemDisable) = 0);        {Set enabled from hi-order bit of itemType}
  2430.                 itemType := BAnd(itemType, $7F);                        {... and mask it to (finally) get itemType}
  2431.                 itemLen := BAnd(typeLen, $FF);                            {Item length is easy}
  2432.                 if itemType <> itemRadio then
  2433.                     radioCount := 0;                                                {If this is not radiobutton, set to init next radiogroup}
  2434.  
  2435.                 case itemType of
  2436.                     itemButton: 
  2437.                         itsPanes.Add(CObject(MakeButton(itsWindow, self, item, enabled)));
  2438.  
  2439.                     itemCheckbox: 
  2440.                         itsPanes.Add(CObject(MakeCheckBox(itsWindow, self, item, enabled)));
  2441.  
  2442.                     itemRadio: 
  2443.                         begin
  2444.                         if radioCount = 0 then begin                        {Need new radio group?}
  2445.                             new(radioGroup);                                            {…yes…}
  2446.                             radioGroup.IDRadioGroup(itsWindow, self, '');
  2447.                             itsRadioGroups.Add(CObject(radioGroup));
  2448.                         end;
  2449.                         radioCount := radioCount + 1;
  2450.  
  2451.                         aPane := MakeRadioButton(itsWindow, radioGroup, item, enabled, radioCount);
  2452.                         itsPanes.Add(CObject(aPane));
  2453.  
  2454.                         radioGroup.AddButton(CDRadioButton(aPane));
  2455.                         if radioCount = 1 then
  2456.                             radioGroup.SetStationID(1);
  2457.                     end;
  2458.  
  2459.                     itemControl: 
  2460.                         itsPanes.Add(CObject(MakeControl(itsWindow, self, item, enabled)));
  2461.  
  2462.                     iconItem: 
  2463.                         itsPanes.Add(CObject(MakeIcon(itsWindow, self, item, enabled)));
  2464.  
  2465.                     picItem: 
  2466.                         itsPanes.Add(CObject(MakePicture(itsWindow, self, item, enabled)));
  2467.  
  2468.                     userItem: 
  2469.                         itsPanes.Add(CObject(MakeUser(itsWindow, self, item, enabled)));
  2470.  
  2471.                     editText: 
  2472.                         begin
  2473.                         aPane := MakeEditText(itsWindow, self, item, enabled);
  2474.                         itsPanes.Add(CObject(aPane));
  2475.                         itsTEPanes.Add(CObject(aPane));
  2476.                     end;
  2477.  
  2478.                     statText: 
  2479.                         itsPanes.Add(CObject(MakeStaticText(itsWindow, self, item, enabled)));
  2480.                 end; {CASE itemType}
  2481.  
  2482.                 {Now advance pointer to next item}
  2483.                 if Odd(itemLen) then                                    {Handle odd-length titles/text}
  2484.                     itemLen := itemLen + 1;
  2485.                 DITLPtr := Ptr(Ord4(DITLPtr) + sizeof(item) - SizeOf(Str255) + itemLen);
  2486.  
  2487.             end; {WITH item DO}
  2488.         end; {FOR index := 0 to nItems}
  2489.  
  2490.         HUnlock(Handle(DITLtmpl));
  2491.         ActivateNextTE;
  2492.  
  2493.         gBartender.UpdateAllMenus;
  2494.         gBartender.DeleteFromBar(NOTHING);
  2495.     end;
  2496.  
  2497. {    ****************************************************    }
  2498. {     Free                                                                                                                        }
  2499. {}
  2500. {    ****************************************************    }
  2501. procedure CDlog.Free;
  2502.     begin
  2503.         if itsRadioGroups <> nil then
  2504.             itsRadioGroups.DisposeAll;
  2505.  
  2506.         inherited Free;
  2507.     end;
  2508.  
  2509. {    ****************************************************    }
  2510. {     Close                                                                                                                    }
  2511. {}
  2512. {        Close is the only way to dismiss the dialog, though it can be called through            }
  2513. {        CloseWind or when the application is quitting.  When the user presses OK or        }
  2514. {        cancel, the Close message should be sent to the Dlog.  This method creates            }
  2515. {        an urgent chore that sends the Free message to the Dlog.  This approach avoids    }
  2516. {        trouble caused by Free'ing the object (as a result of CDirector.Close)     when        }
  2517. {        methods that are still in the call chain depend on the object's existence.                }
  2518. {}
  2519. {    ****************************************************    }
  2520. function CDlog.Close (quitting: boolean): boolean;
  2521.     begin
  2522.         Close := inherited Close(quitting);
  2523.     end;
  2524.  
  2525. {    ****************************************************    }
  2526. {     GetDItem                                                                                                                }
  2527. {}
  2528. {    ****************************************************    }
  2529. procedure CDlog.GetDItem (item: integer;
  2530.                                 var kind: integer;
  2531.                                 var h: CObject;
  2532.                                 var r: Rect);
  2533.     begin
  2534.         h := itsPanes.NthItem(item);
  2535.         CPane(h).GetFrame(r);
  2536.         CPane(h).FrameToEnclR(r);
  2537.         kind := 0;
  2538.     end;
  2539.  
  2540. {    ****************************************************    }
  2541. {     ActivatePrevTE                                                                                                    }
  2542. {}
  2543. {            Make the previous CDEditText object in the itsTEPanes list the active            }
  2544. {            editText pane.                                                                                                }
  2545. {}
  2546. {    ****************************************************    }
  2547. procedure CDlog.ActivatePrevTE;
  2548.     var
  2549.         numTE: integer;
  2550.  
  2551.     begin
  2552.         numTE := itsTEPanes.GetNumItems;
  2553.         if numTE > 0 then begin
  2554.             if itsActiveTE > 0 then                                                            {Deactivate current, if any}
  2555.                 CDEditText(itsGopher).Deactivate;
  2556.  
  2557.             itsActiveTE := itsActiveTE - 1;                                                    {Go to previous...}
  2558.             if itsActiveTE < 1 then
  2559.                 itsActiveTE := numTE;                                                            {Or... around to last}
  2560.  
  2561.             itsGopher := CDEditText(itsTEPanes.NthItem(itsActiveTE));        {Activate new}
  2562.             CDEditText(itsGopher).SetSelect(0, 32767);
  2563.             CDEditText(itsGopher).Activate;
  2564.             gGopher := itsGopher;
  2565.         end; {if numTE > 0}
  2566.     end; {ActivatePrevTE}
  2567.  
  2568.  
  2569. {    ****************************************************    }
  2570. {     ActivateNextTE                                                                                                    }
  2571. {}
  2572. {            Make the next CDEditText object in the itsTEPanes list the active                    }
  2573. {            editText pane.                                                                                                }
  2574. {}
  2575. {    ****************************************************    }
  2576. procedure CDlog.ActivateNextTE;
  2577.     var
  2578.         numTE: integer;
  2579.  
  2580.     begin
  2581.         numTE := itsTEPanes.GetNumItems;
  2582.         if numTE > 0 then begin
  2583.             if itsActiveTE > 0 then                                                            {Deactivate current, if any}
  2584.                 CDEditText(itsGopher).Deactivate;
  2585.  
  2586.             itsActiveTE := itsActiveTE + 1;                                                {Go to next...}
  2587.             if itsActiveTE > itsTEPanes.GetNumItems then
  2588.                 itsActiveTE := 1;                                                                    {Or... back to first}
  2589.  
  2590.             itsGopher := CDEditText(itsTEPanes.NthItem(itsActiveTE));        {Activate new}
  2591.             CDEditText(itsGopher).SetSelect(0, 32767);
  2592.             CDEditText(itsGopher).Activate;
  2593.             gGopher := itsGopher;
  2594.         end; {if numTE > 0}
  2595.     end; {ActivateNextTE}
  2596.  
  2597.  
  2598. {    ****************************************************    }
  2599. {     ActivateThisTE                                                                                                    }
  2600. {}
  2601. {            Make the specified CDEditText object the active editText pane.                        }
  2602. {}
  2603. {    ****************************************************    }
  2604. procedure CDlog.ActivateThisTE (tePane: CDEditText);
  2605.     var
  2606.         teIndex: integer;
  2607.  
  2608.     begin
  2609.         teIndex := itsTEPanes.FindIndex(CObject(tePane));                    {Get index to specified pane...}
  2610.         if teIndex <> itsActiveTE then begin
  2611.             if itsActiveTE > 0 then                                                        {Deactivate current, if any}
  2612.                 CDEditText(itsGopher).Deactivate;
  2613.  
  2614.             itsActiveTE := teIndex;                                                            {Save pane index}
  2615.  
  2616.             itsGopher := tePane;                                                                {Activate it}
  2617.             tePane.SetSelect(0, 32767);
  2618.             tePane.Activate;
  2619.             gGopher := itsGopher;
  2620.         end; {if teIndex <> itsActiveTE}
  2621.     end; {ActivateThisTE}
  2622.  
  2623.  
  2624. {    ****************************************************    }
  2625. {     UpdateMenus                                                                                                        }
  2626. {}
  2627. {            Handle commands.                                                                                            }
  2628. {}
  2629. {            Perform menu management tasks.                                                                    }
  2630. {            method.                                                                                                            }
  2631. {}
  2632. {    ****************************************************    }
  2633. procedure CDlog.UpdateMenus;
  2634.     begin
  2635.         if itsDocument <> nil then
  2636.             itsDocument.UpdateMenus
  2637.         else
  2638.             inherited UpdateMenus;
  2639.     end;
  2640.  
  2641.  
  2642. {    ****************************************************    }
  2643. {     DoCommand                                                                                                            }
  2644. {}
  2645. {            Handle commands.                                                                                            }
  2646. {}
  2647. {            This method is normally overridden.  Make sure to call the inherited                }
  2648. {            method.                                                                                                            }
  2649. {}
  2650. {    ****************************************************    }
  2651. procedure CDlog.DoCommand (theCommand: longint);
  2652.     begin
  2653.         case theCommand of
  2654.             cmdOKEquiv: 
  2655.                 DoButton(1);
  2656.  
  2657.             cmdCancelEquiv: 
  2658.                 DoButton(2);
  2659.  
  2660.             cmdClose: 
  2661.                 begin
  2662.                 if Close(FALSE) then
  2663.                     ;
  2664.             end;
  2665.  
  2666.             otherwise
  2667.                 if itsDocument <> nil then
  2668.                     itsDocument.DoCommand(theCommand)
  2669.                 else
  2670.                     inherited DoCommand(theCommand);
  2671.         end; {case}
  2672.     end; {DoCommand}
  2673.  
  2674.  
  2675. {    ****************************************************    }
  2676. {     SetEdit                                                                                                                    }
  2677. {}
  2678. {            Send the SetEdit message to a CDEditText pane.                                                }
  2679. {    ****************************************************    }
  2680. procedure CDlog.SetEdit (                                                        { Set editing control variables }
  2681.                                 anItem: integer;                                        { Item number of edit text field }
  2682.                                 aFilter: integer;                                        { The filter mask }
  2683.                                 aMaxLength: integer);                                { The maximum length }
  2684.     var
  2685.         aText: CDEditText;
  2686.  
  2687.     begin
  2688.         aText := CDEditText(itsPanes.NthItem(anItem));
  2689.         aText.SetEdit(aFilter, aMaxLength);
  2690.     end;
  2691.  
  2692.  
  2693. {    ****************************************************    }
  2694. {     GetIText                                                                                                                }
  2695. {}
  2696. {            Get the text for one of the EditText or StaticText panes.                                }
  2697. {}
  2698. {    ****************************************************    }
  2699. procedure CDlog.GetIText (                                                        { Get item text }
  2700.                                 anItem: integer;                                        { Item number of text field }
  2701.                                 var str: Str255);                                    { The text in a string }
  2702.     var
  2703.         aText: CStaticText;
  2704.         theChars: CharsHandle;
  2705.         theLength: longint;
  2706.  
  2707.     begin
  2708.         str := '';
  2709.         aText := CStaticText(itsPanes.NthItem(anItem));
  2710.         if Member(aText, CStaticText) then begin
  2711.             theChars := aText.GetTextHandle;
  2712.             theLength := GetHandleSize(Handle(theChars));
  2713.             if theLength > 255 then
  2714.                 theLength := 255;
  2715. {$PUSH}
  2716. {$R-}
  2717.             str[0] := Chr(theLength);
  2718. {$POP}
  2719.             if theLength > 0 then
  2720.                 BlockMove(Ptr(theChars^), @str[1], theLength);
  2721.         end;
  2722.     end;
  2723.  
  2724.  
  2725. {    ****************************************************    }
  2726. {     SetIText                                                                                                                }
  2727. {}
  2728. {            Set the text of a CStaticText or CDEditText pane.                                            }
  2729. {}
  2730. {    ****************************************************    }
  2731. procedure CDlog.SetIText (                                                        { Set item text }
  2732.                                 anItem: integer;                                        { Item number of text field }
  2733.                                 str: Str255);                                            { New text for the item }
  2734.     var
  2735.         aText: CStaticText;
  2736.  
  2737.     begin
  2738.         aText := CStaticText(itsPanes.NthItem(anItem));
  2739.         aText.Prepare;
  2740.         aText.SetTextString(str);
  2741.     end;
  2742.  
  2743.  
  2744. {    ****************************************************    }
  2745. {    DoKeyDown                                                                                                            }
  2746. {}
  2747. {        Handle keydowns.    Only used with dialogs without editText fields.                        }
  2748. {}
  2749. {    ****************************************************    }
  2750. procedure CDlog.DoKeyDown (                            { Handle key-down }
  2751.                                 theChar: char;                        { Key character }
  2752.                                 keyCode: Byte;                        { Key code }
  2753.                                 macEvent: EventRecord);        { Mac event record }
  2754.  
  2755.     const
  2756.         ETX = $03;
  2757.         CR = $0D;
  2758.         ESC = $1B;
  2759.         LKEY = $1C;
  2760.         DKEY = $1F;
  2761.  
  2762.     var
  2763.         cmd: longint;
  2764.  
  2765.     begin
  2766.         cmd := 0;
  2767.  
  2768.         {Check for special characters}
  2769.         if Ord(theChar) in [LKEY..DKEY] then                        { Intercept arrow keys }
  2770.             cmd := cmdArrowLeft + Ord(theChar) - LKEY        { ... to do list movement }
  2771.  
  2772.         else if Ord(theChar) in [ETX, CR] then                    { Enter and Return = OK }
  2773.             cmd := cmdOkEquiv                                                { Simulate clicking OK }
  2774.  
  2775.         else if Ord(theChar) = ESC then                                { ESC = CANCEL }
  2776.             cmd := cmdCancelEquiv;                                        { Simulate clicking Cancel }
  2777.  
  2778.         if cmd <> 0 then
  2779.             DoCommand(cmd)
  2780.         else
  2781.             inherited DoKeyDown(theChar, keyCode, macEvent);    { Everything else}
  2782.     end;
  2783.  
  2784.  
  2785. {    ****************************************************    }
  2786. {     DefaultButton                                                                                                        }
  2787. {}
  2788. {            Simulate clicking a button.      Make sure you pass the itemNumber of a button!    }
  2789. {}
  2790. {    ****************************************************    }
  2791. procedure CDlog.DoButton (itemNumber: integer);
  2792.     const
  2793.         hiliteDelay = 8;
  2794.         ON = 1;
  2795.         OFF = 0;
  2796.  
  2797.     var
  2798.         aButton: CDButton;
  2799.         aLong: longint;
  2800.  
  2801.     begin
  2802.         aButton := CDButton(itsPanes.NthItem(itemNumber));
  2803.         if (aButton <> nil) & Member(aButton, CDButton) & aButton.WantsClicks & (aButton.macControl^^.contrlHilite <> 255) then begin
  2804.             aButton.Hilite(ON);
  2805.             Delay(hiliteDelay, aLong);
  2806.             aButton.Hilite(OFF);
  2807.  
  2808.             aButton.DoGoodClick(0);
  2809.         end;
  2810.     end;
  2811.  
  2812.  
  2813. {    ****************************************************    }
  2814. {     GetControlHandle                                                                                                    }
  2815. {}
  2816. {            Get the ControlHandle for the given item.                                                        }
  2817. {    ****************************************************    }
  2818.  
  2819. function CDlog.GetControlHandle (itemNumber: integer): ControlHandle;
  2820.     var
  2821.         aControl: CDControl;
  2822.  
  2823.     begin
  2824.         aControl := CDControl(itsPanes.NthItem(itemNumber));
  2825.         if (aControl <> nil) & Member(aControl, CDControl) then
  2826.             GetControlHandle := aControl.macControl
  2827.         else
  2828.             GetControlHandle := nil;
  2829.     end;
  2830.  
  2831.  
  2832. {    ****************************************************    }
  2833. {     MakeButton                                                                                                            }
  2834. {}
  2835. {    ****************************************************    }
  2836. function CDlog.MakeButton (anEnclosure: CView;
  2837.                                 aSupervisor: CBureaucrat;
  2838.                                 item: CDDitlItemRec;
  2839.                                 enabled: boolean): CPane;
  2840.     var
  2841.         button: CDButton;
  2842.  
  2843.     begin
  2844.         new(button);
  2845.         button.IDButton(anEnclosure, aSupervisor, item);
  2846.  
  2847.         button.SetWantsClicks(enabled);
  2848.         MakeButton := button;
  2849.     end;
  2850.  
  2851.  
  2852. {    ****************************************************    }
  2853. {     MakeCheckBox                                                                                                        }
  2854. {}
  2855. {    ****************************************************    }
  2856. function CDlog.MakeCheckBox (anEnclosure: CView;
  2857.                                 aSupervisor: CBureaucrat;
  2858.                                 item: CDDitlItemRec;
  2859.                                 enabled: boolean): CPane;
  2860.     var
  2861.         check: CDCheckBox;
  2862.  
  2863.     begin
  2864.         new(check);
  2865.         check.IDCheckBox(anEnclosure, aSupervisor, item);
  2866.  
  2867.         check.SetWantsClicks(enabled);
  2868.         MakeCheckBox := check;
  2869.     end;
  2870.  
  2871.  
  2872. {    ****************************************************    }
  2873. {     MakeRadioButton                                                                                                    }
  2874. {}
  2875. {    ****************************************************    }
  2876. function CDlog.MakeRadioButton (anEnclosure: CView;
  2877.                                 aSupervisor: CBureaucrat;
  2878.                                 item: CDDitlItemRec;
  2879.                                 enabled: boolean;
  2880.                                 anID: integer): CPane;
  2881.     var
  2882.         radio: CDRadioButton;
  2883.  
  2884.     begin
  2885.         new(radio);
  2886.         radio.IDRadioButton(anEnclosure, aSupervisor, item, anID);
  2887.  
  2888.         radio.SetWantsClicks(enabled);
  2889.         MakeRadioButton := radio;
  2890.     end;
  2891.  
  2892.  
  2893. {    ****************************************************    }
  2894. {     MakeControl                                                                                                            }
  2895. {}
  2896. {    ****************************************************    }
  2897. function CDlog.MakeControl (anEnclosure: CView;
  2898.                                 aSupervisor: CBureaucrat;
  2899.                                 item: CDDitlItemRec;
  2900.                                 enabled: boolean): CPane;
  2901.     var
  2902.         control: CDControl;
  2903.  
  2904.     begin
  2905.         new(control);
  2906.         control.IDControl(anEnclosure, aSupervisor, item);
  2907.  
  2908.         control.SetWantsClicks(enabled);
  2909.         MakeControl := control;
  2910.     end;
  2911.  
  2912.  
  2913. {    ****************************************************    }
  2914. {     MakeIcon                                                                                                                }
  2915. {}
  2916. {    ****************************************************    }
  2917. function CDlog.MakeIcon (anEnclosure: CView;
  2918.                                 aSupervisor: CBureaucrat;
  2919.                                 item: CDDitlItemRec;
  2920.                                 enabled: boolean): CPane;
  2921.     var
  2922.         icon: CDIcon;
  2923.         resId: integer;
  2924.  
  2925.     begin
  2926.         new(icon);
  2927.         resID := IntPtr(Ord(@item) + sizeOf(CDDitlItemRec) - SizeOf(Str255))^;    {Get resource id}
  2928.         with item.boundsRect do
  2929.             icon.IDIcon(itsWindow, self, right - left, bottom - top, left, top, sizFIXEDSTICKY, sizFIXEDSTICKY, resID);
  2930.  
  2931.         icon.SetWantsClicks(enabled);
  2932.         MakeIcon := icon;
  2933.     end;
  2934.  
  2935.  
  2936. {    ****************************************************    }
  2937. {     MakePicture                                                                                                            }
  2938. {}
  2939. {    ****************************************************    }
  2940. function CDlog.MakePicture (anEnclosure: CView;
  2941.                                 aSupervisor: CBureaucrat;
  2942.                                 item: CDDitlItemRec;
  2943.                                 enabled: boolean): CPane;
  2944.     var
  2945.         picture: CDPicture;
  2946.         resId: integer;
  2947.  
  2948.     begin
  2949.         new(picture);
  2950.         resID := IntPtr(Ord(@item) + sizeOf(CDDitlItemRec) - SizeOf(Str255))^;    {Get resource id}
  2951.         with item.boundsRect do
  2952.             picture.IDPicture(itsWindow, self, right - left, bottom - top, left, top, sizFIXEDSTICKY, sizFIXEDSTICKY, resID);
  2953.  
  2954.         picture.SetWantsClicks(enabled);
  2955.         MakePicture := picture;
  2956.     end;
  2957.  
  2958.  
  2959. {    ****************************************************    }
  2960. {     MakeUser                                                                                                                }
  2961. {}
  2962. {    ****************************************************    }
  2963. function CDlog.MakeUser (anEnclosure: CView;
  2964.                                 aSupervisor: CBureaucrat;
  2965.                                 item: CDDitlItemRec;
  2966.                                 enabled: boolean): CPane;
  2967.     var
  2968.         user: CDUser;
  2969.  
  2970.     begin
  2971.         new(user);
  2972.         with item.boundsRect do
  2973.             user.IDUser(itsWindow, self, right - left + 1, bottom - top + 1, left, top, sizFIXEDSTICKY, sizFIXEDSTICKY);
  2974.  
  2975.         user.SetWantsClicks(enabled);
  2976.         MakeUser := user;
  2977.     end;
  2978.  
  2979.  
  2980. {    ****************************************************    }
  2981. {     MakeEditText                                                                                                        }
  2982. {}
  2983. {    ****************************************************    }
  2984. function CDlog.MakeEditText (anEnclosure: CView;
  2985.                                 aSupervisor: CBureaucrat;
  2986.                                 item: CDDitlItemRec;
  2987.                                 enabled: boolean): CPane;
  2988.     var
  2989.         edit: CDEditText;
  2990.         border: CBorder;
  2991.         aStr: Str255;
  2992.  
  2993.     begin
  2994.         new(border);
  2995.         with item.boundsRect do
  2996.             border.IBorder(anEnclosure, aSupervisor, right - left + 2 * BORDER_OFFSET, bottom - top + 2 * BORDER_OFFSET, left - BORDER_OFFSET, top - BORDER_OFFSET, sizFIXEDLEFT, sizFIXEDTOP);
  2997.         border.SetWantsClicks(FALSE);
  2998.  
  2999.         new(edit);
  3000.         with item.boundsRect do
  3001.             edit.IDEditText(anEnclosure, aSupervisor, right - left + 1, bottom - top + 1, left, top, sizFIXEDLEFT, sizFIXEDTOP, -1);
  3002.  
  3003.         edit.SetWantsClicks(enabled);
  3004.         aStr := StringPtr(Ord(@item) + sizeOf(CDDitlItemRec) - SizeOf(str255) - 1)^;
  3005.         edit.SetTextString(aStr);
  3006.         edit.Deactivate;
  3007.         MakeEditText := edit;
  3008.     end;
  3009.  
  3010.  
  3011. {    ****************************************************    }
  3012. {     MakeStatitText                                                                                                    }
  3013. {}
  3014. {    ****************************************************    }
  3015. function CDlog.MakeStaticText (anEnclosure: CView;
  3016.                                 aSupervisor: CBureaucrat;
  3017.                                 item: CDDitlItemRec;
  3018.                                 enabled: boolean): CPane;
  3019.     var
  3020.         static: CStaticText;
  3021.         aStr: Str255;
  3022.  
  3023.     begin
  3024.         new(static);
  3025.         with item.boundsRect do
  3026.             static.IStaticText(anEnclosure, aSupervisor, right - left + 1, bottom - top + 1, left, top, sizFIXEDSTICKY, sizFIXEDSTICKY, -1);
  3027.  
  3028.         static.SetWantsClicks(enabled);
  3029.         aStr := StringPtr(Ord(@item) + sizeOf(CDDitlItemRec) - SizeOf(str255) - 1)^;
  3030.         static.SetTextString(aStr);
  3031.         MakeStaticText := static;
  3032.     end;
  3033.  
  3034. end. {CDlog}